什么是强缓存
- 强制缓存:设置缓存机制后,前端第一次请求到资源会把资源缓存到客户端,如果下次请求时资源没有过期,那么直接调用本地缓存的资源,如果过期则重新发送请求。
- 强制缓存由服务端开启,利用
http
头中的Expires
和Cache-Control
两个字段来控制 - 注意点:
- 强制缓存不用和服务端交互;
- 客户端设置请求头
Cache-Control
,只有为:no-store
、no-cache
、max-age=0
才会生效(也就是客户端不想走强制缓存的时候生效。no-cache意思是不走强缓存,走协商缓存;no-store意思是不使用缓存), - 强缓存返回状态码为200;
- post请求不能设置缓存,只有get请求有效。
演示说明
-
Expires
:表示响应头里面的过期时间,如果超过改时间,浏览器再次加载资源时(例如刷新页面,就会重新请求该资源文件,否则不会重新请求,会使用浏览器存储起来的缓存)
从这里可以看出,请求该文件的时间是
1
该文件过期的缓存时间是2
(即1分钟以内请求该资源浏览器将使用缓存,否则重新请求)而从
图二
更能清晰表面,第一次请求
的时候使用的是请求的资源
,第二次请求
的时候使用的是缓存资源
什么是协商缓存
- 协商缓存:第一次请求资源时,服务器会返回资源以及资源标识,当下次请求时,会对比资源标识,如果一致,则只返回状态码304,不用返回资源,如果不一致,则会返回资源和新的资源标识。
- 协商缓存主要依赖的响应头包括
last-modified
和ETag
。 - 注意点:
- 协商缓存需要和服务器交互;
- 请求资源命中协商缓存后,返回的状态码为
304
; -
last-modified
记录资源最后修改的时间。启用后, 请求资源之后的响应头会增加一个last-modified字段
演示说明:
- 从这里可以看出返回状态码
304
表示当前为协商缓存数据。 - 图二
Etag
表示当前文件的标识,服务器上存储着文件的Etag
字段,可以在与每次客户端请求头里面的If-no-match
的字段进行比较。如果相等,则表示未修改,响应304;反之,则表示已修改,响应200状态码,返回数据。 -
Last-Modified
则表示该资源文件的最后一次修改的时间,它会与每次客户端请求头里面的If-Modified-Since
字段进行对比,如果相等,则表示未修改,响应304状态码,告诉客户端可继续使用缓存;反之,则表示修改了,响应200状态码,返回新的资源数据
。
使用什么方案及如何配置?
-
方案:
- 前端
协商缓存
,后端强缓存
- 前端
-
为什么?
因为进行
JS CSS 图片资源
这种一般打包后都不会随便修改,所以直接使用强缓存即可。因为
HTML
文件引入的CSS js资源
存在修改的情况,所以使用协商缓存。(场景需求:需将线上P标签
的字体颜色变为红色
,经过打包后重新生成新的HTML
文件)如下所示,引入的
css js
文件经打包后名字(也可以手动重命名)重新发生了改变,html
重新上线后会请求新的css js文件
,达到修改的效果。-
注意点:推荐采用
非覆盖式
部署,避免直接替换后某些用户无法访问到旧的资源文件,出现报错的情况,即保留除HTML
文件外的其它全部文件,将新的资源文件直接上传,同时HTML
文件覆盖后,进行必要留存
和文件命名
,方便需要时进行版本回滚
,例如HTML-v1.1
//原HTML文件 <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>node demo</title> <link rel="stylesheet" href="/index-s3ds45d.css"> </head> <body> <p>hello world</p> <script src="/index-lsdsa876sd.js"></script> </body> //新HTML文件 <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>node demo</title> <link rel="stylesheet" href="/index-fsdsd09d1.css"> </head> <body> <p>hello world</p> <script src="/index-gses456h.js"></script> </body>
-
如何配置?
-
前端HTML文件配置
//禁用缓存如下: <meta http-equiv="pragma" content="no-cache"> // 仅有IE浏览器才识别的标签,不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求 <meta http-equiv="cache-control" content="no-cache"> // 其他主流浏览器识别的标签 <meta http-equiv="expires" content="0"> // 仅有IE浏览器才识别的标签,该方式仅仅作为知会IE缓存时间的标记,你并不能在请求或响应报文中找到Expires字段
后端可以通过
nginx
进行配置(这里为了演示,所以设置缓存周期为60秒)
-
HTML字段补充说明
expires
可以用于设定网页的到期时间。一旦网页过期,必须到服务器上重新传输。
cache-control
指定请求和响应遵循的缓存机制。共有以下几种用法:
-
no-cache
: 先发送请求,与服务器确认该资源是否被更改,如果未被更改,则使用缓存。 -
no-store
: 不允许缓存,每次都要去服务器上,下载完整的响应。(安全措施) -
public
: 缓存所有响应,但并非必须。因为max-age也可以做到相同效果 -
private
: 只为单个用户缓存,因此不允许任何中继进行缓存。(比如说CDN就不允许缓存private的响应) -
max-age
: 表示当前请求开始,该响应在多久内能被缓存和重用,而不去服务器重新请求。例如:max-age=60表示响应可以再缓存和重用 60 秒。