JavaScript 页面缓存
1.前言
- 由来:默认环境中,当浏览器重复访问一个资源时,为节省资源与性能,浏览器将其缓存,后续的请求不再从服务器下载该资源,而是直接从本地缓存中读取,默认时没有强制缓存的
- 副作用:当服务器资源更新时,浏览器无法得知,依旧加载的是旧资源
- 缓存类型:强制缓存和协商缓存
2.强制缓存
- 作用:告诉浏览器,强制缓存生效期间,再次拿当前资源不要发请求,直接读取磁盘
- 通过 Expires 设定缓存的过期时间,这个时间是服务器设定的,但是如果客户端与服务端时间不同步,就会产生问题,所以不推荐使用,现在已被后面的 Cache-Control 替代
//强制缓存(设置过期时间)
var expires = new Date()
//1分钟过期
expires.setMinutes(expires.getMinutes() + 1)
res.setHeader('Expires', expires.toUTCString())

- 通过 Cache-Control 设定缓存有效时长(秒),以客户端时间为准,往后计算缓存有效期
res.setHeader("Cache-Control","max-age=7200")

3.协商缓存
- 说明:顾名思义,就是在使用本地缓存之前,向服务器发起GET请求,与之协商当前的缓存是否已经过期,如果已经过期,则下载最新的资源,如果没过期,则读取缓存
- 原理:资源缓存时,附带一个标识(文件最终修改时间,或者文件内容hash),下次请求时然后拿这个标识与服务器的标识 做对比,如果不一致,则返回最新资源,如果一直,则返回返回状态码 304,让浏览器读本地缓存
- 注意:需要设定 Cache-Control 为 no-cache (这里的no-cache含义并不是说不要缓存,而说的是协商缓存,只有设定为no-store才是禁用缓存,设置 max-age 也是可以启用缓存的,只不过此时强制换成优先级比协商缓存高)
- last-modified:通过获取文件最终修改时间作为标识进行判断,下一次请求时,请求头会自动添加 "if-modified-since" 字段并带上之前返回的last-modified的值,服务器就可以知道当前资源的最终修改时间,以此来判断返回的内容。这种方式有2个弊端:第一,文件可能被动过,但是里面内容没变,可能只是重命名,第二,修改时间戳精确到秒,做不到毫秒级的识别判定
//获取文件
var data = fs.readFileSync('./www/index.js')
//获取文件时间
var {mtime} = fs.statSync('./www/index.js')
//设置最终修改时间
res.setHeader("last-modified", mtime.toUTCString())
//开启协商缓存
res.setHeader('Cache-Control','no-cache')
//对比协商缓存的时间,来确定返回结果
var ifModifiedSince = req.headers["if-modified-since"]
if(ifModifiedSince == mtime.toUTCString()){
//告诉浏览器资源未发生变化,让他读缓存
res.statusCode = 304
res.end()
}else{
//返回图片
res.end(data)
}



- Etag:通过文件内容进行hash运算生成字符串(hash运算使用的包名叫 etag),以此带代替last-modified,下一次请求时,请求头会自动添加 "If-None-Match" 字段并带上之前返回的Etag的值。缺点是hash运算计算开销大,影响性能
//获取文件
var data = fs.readFileSync('./www/index.js')
//hash运算生成字符串
var etagContent = etag(data)
//添加到响应头
res.setHeader('etag',etagContent)
//开启协商缓存
res.setHeader('Cache-Control','no-cache')
//判断内容是否发生变化
var ifNoneMatch = req.headers["if-none-match"]
if(ifNoneMatch == etagContent){
//告诉浏览器资源未发生变化,让他读缓存
res.statusCode = 304
res.end()
}else{
//返回图片
res.end(data)
}


4.缓存策略
- HTML文件:HTML文件包含了很多资源的引用,推荐使用协商缓存,当文件修改时才获取最新版本
- 图片,字体文件等静态资源:这类资源要么不改,要么会整体替换掉,推荐使用强制缓存,但是要注意缓存的时间,缓存的东西太多客户端有压力
- 固定URL的js,css文件:这类文件修改频繁,推荐使用协商缓存,当文件修改时才获取最新版本
- 编译后的js,css文件:这里文件常见于脚手架项目,打包编译后文件名是随机变动的,和图片类似,推荐使用强制缓存
5.动态资源链接
- 原理:当一个请求路径不变,但是携带的参数发生变化时,浏览器视为新请求,不读取缓存数据
//在资源链接后面添加版本号(v=100),修改通过这个版本号(v=101),强制客户端更新资源
<script src="./index.js?v=100"></script>
- 全局控制:对资源链接的版本号进行动态拼接,只要修改系统版本号,所有资源强制升级
6.手动清除缓存
- F12->网络->选中请求->清除缓存

- 页面强制重载

7.meta标签中的Cache-Control
- 语法
<meta http-equiv="Cache-Control" content="no-cache">
- 说明:meta标签在HTML文档中用于向浏览器提供关于如何缓存文档的指令。然而,这些指令并不总是被所有浏览器遵循,因为它们的实现可能因浏览器而异。这些指令通常只影响对HTML文档的缓存决策,而不是文档中包含的资源(如CSS、JavaScript文件或图片)的缓存
- 对比HTTP的Cache-Control:HTTP响应头中的Cache-Control指令是由服务器发送的,用于精确控制浏览器(以及其他HTTP缓存)对响应的缓存方式。这些指令对于所有类型的资源(HTML文档、CSS、JavaScript、图片等)都有效,由于HTTP响应头是由服务器直接发送给浏览器的,因此这些指令通常具有比HTML文档中的标签更高的优先级。浏览器在决定是否缓存资源时,会优先考虑HTTP响应头中的Cache-Control指令。
8.离线浏览
- 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本
- manifest 的技术已被 web 标准废弃,不再推荐使用此功能
JavaScript 页面缓存的更多相关文章
- angular页面缓存与页面刷新
angularJS学习笔记:页面缓存与页面刷新 遇到的问题 现在存在这样一个问题,登录前与登录成功后是同一个页面,只不过通过ngIf来控制哪部分显示,图像信息如下: 所以,整体工作不是很难,无非就 ...
- Flask 页面缓存逻辑,jinja2 过滤器,测试器
回调接入点-页面缓存逻辑 from flask import Flask,request,render_template from werkzeug.contrib.cache import Simp ...
- springboot和redis处理页面缓存
页面缓存是应对高并发的一个比较常见的方案,当请求页面的时候,会先查询redis缓存中是否存在,若存在则直接从缓存中返回页面,否则会通过代码逻辑去渲染页面,并将渲染后的页面缓存到redis中,然后返回. ...
- 设置清除html5页面缓存
设置清除html5页面缓存 html5端设置 meta 标签: <meta http-equiv="Pragma" content="no-cache" ...
- vue中keep-alive,include的指定页面缓存问题
做vue项目时,有时要在某些页面做缓存,而其它页面不要.比如:A:首页,B:获取所有订单页面,C:订单详情页面:从A(首页)进入 B(获取所有订单)时应该不缓存,B(所有订单)进入 C(订单详情)订单 ...
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解
转载:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...
- cache-contro页面缓存处理设置
<meta http-equiv="pragma" content="no-cache">,pragma与no-cache用于定义页面缓存,不缓存页 ...
- webform的页面缓存
给页面添加<%@ OutputCache Duration="10" VaryByParam="*"%>标签就可以启用页面缓存. Duration表 ...
- 【WP开发】正确理解页面缓存
注:本文内容面向Runtime App. 在新建项目后,细心观察,你会发现在App类中有以下代码: // TODO: 将此值更改为适合您的应用程序的缓存大小 rootFrame.CacheSize = ...
随机推荐
- 合合信息通过ISO/IEC国际标准双认证,为全球用户提供高合规标准AI服务
互联网.AI等技术的全球普及为人们提供便捷服务的同时,也带来了信息安全领域的诸多挑战.保护用户隐私及数据安全,是科技企业规范.健康发展的重心.近期,上海合合信息科技股份有限公司(简称"合合信 ...
- Angular 18+ 高级教程 – Change Detection & Ivy rendering engine
前言 不熟悉 Angular 的朋友可能不了解 Change Detection 和目前当火的 Signal 之间的关系,以至于认为现在应该要学习新潮流 Signal 而不是已经过时的 Change ...
- JavaScript – Promise
前言 我学 Promise 的时候, 那时还没有 es6. 曾经还自己实现过. 但时隔多年, 现在 es6 的 promise 已经很完善了. 这篇作为一个简单的复习. (毕竟我已经 1 年多没有写 ...
- 人脸识别 face detect & recognize
前言 最近有一个项目要升级. 它是一个在线教育的 web app. 由于学生年龄小, 不适合用 username/password 这种方式做登入. 所以项目开始之初是使用 RFID 来登入的. 但由 ...
- 应聘软件测试 HR 会问到哪些问题?收藏这一篇就够了!
1.你还有收到其他offer吗? 其实hr问你offer情况,是对你感兴趣,想要进一步了解你,看下你的市场竞争力. 但注意不要太坦诚的说:我还没有offer或者收到两个offer还想对比对比:也不要撒 ...
- `std::optional` 函数返回值
std::optional 是 C++17 中引入的一个模板类,用于表示一个值可能存在也可能不存在的情况. 它可以存储一个值,或者表示没有值的状态,类似于其他编程语言中的"可选"类 ...
- 九问 GBase | 如何看待“科技制裁”?如何助力中国数据库国产化落地?
导读: Oracle.SAP.Apple.Google.Github等国际科技巨头纷纷宣布停止在俄罗斯业务,英特尔.AMD.戴尔等科技企业也被曝已中断向俄供货.当全面科技制裁来临,俄罗斯将如何应对此次 ...
- iotdb时序数据库常见使用命令
docker 安装IOTDB核心代码: #docker启动 docker run -d -p 6667:6667 -p 31999:31999 -p 8181:8181 --name some-iot ...
- Docker挂载jar包运行脚本
下载镜像 docker pull openjdk:8 执行命令 docker run -d -p 9001:8081 -v /opt/springboot-docker-1.0.jar:/var/li ...
- "开源"是什么?为啥这么火?一定免费吗?
在科技快速发展的今天,"开源"一词频频出现在我们的视野中.究竟什么是开源?为何它能在技术圈引发如此热潮? 开源软件到底有什么魅力?它是如何改变软件开发和使用的方式的?开源软件是 ...