引言
HTTP 缓存按照失效策略可以分为以下两类:
- 强缓存
- 协商缓存
HTTP 缓存规则是:
- 频繁变动的资源,比如 HTML,采用协商缓存
- CSS、JS、图片资源等采用强缓存,使用 hash 命名
强缓存
Expires
Expires 首部字段是 HTTP/1.0 中定义缓存的字段,其给出了缓存过期的绝对时间,即在此时间之后,响应资源过期,属于实体首部字段。
Expires: Wed, 11 May 2022 03:50:47 GMT
Cache-Control
Cache-Control 首部字段是 HTTP/1.1 中定义缓存的字段,其用于控制缓存的行为,可以组合使用多种指令,多个指令之间可以通过 “,” 分隔,属于通用首部字段。常用的指令有: max-age、s-maxage、public/private、no-cache/no store 等。
- max-age
max-age 指令给出了缓存过期的相对时间,单位为秒数。当其与 Expires 同时出现时,max-age 的优先级更高。但往往为了做向下兼容,两者都会经常出现在响应首部中
- s-maxage
s-maxage 与 max-age 不同之处在于,其只适用于公共缓存服务器,比如资源从源服务器发出后又被中间的代理服务器接收并缓存
当使用 s-maxage 指令后,公共缓存服务器将直接忽略 Expires 和 max-age 指令的值
- public/private
public 指令表示该资源可以被任何节点缓存(包括客户端和代理服务器)
private 指令表示该资源只提供给客户端缓存,代理服务器不会进行缓存。同时当设置了 private 指令后 s-maxage 指令将被忽略。
- no-cache/no-store
1、no-cache、no store 指令,需要注意的是这两个指令在请求和响应中都可以使用
2、响应首部中被使用时, no store 才是真正的不进行任何缓存
3、当 no-cache 在请求首部中被使用时,表示告知(代理)服务器不直接使用缓存,要求向源服务器发起请求
4、当 no-cache 在响应首部中被返回时,表示客户端可以缓存资源,但每次使用缓存资源前都必须先向服务器确认其有效性,这对每次访问都需要确认身份的应用来说很有用
5、也可以在代码里加入 meta 标签的方式来修改资源的请求首部
<meta http-equiv="Cache-Control" content="no-cache" />
协商缓存
浏览器启用协商缓存的前提是强缓存失效,但是反过来强缓存失效并不一定导致浏览器启用协商缓存
缓存标识
Last-Modified 与 ETag
ETag 的优先级要高于 last-modified,当两者同时出现时,只有 ETag 会生效
Last-Modified
- Last-Modified
代表资源的最后修改时间,其属于响应首部字段,当浏览器第一次接收到服务器返回资源的 Last-Modified 值后,其会把这个值存储起来
Last-Modified: Fri , 14 May 2021 17:23:13 GMT
- If-Modified-Since
再下次访问该资源时通过携带 If-Modified-Since 请求首部发送给服务器验证该资源有没有过期,如果在 If-Modified-Since 字段指定的时间之后资源发生了更新,那么服务器会将更新的资源发送给浏览器(状态码200)并返回最新的 Last-Modified 值,浏览器收到资源后会更新缓存的 If-Modified-Since 的值
If-Modified-Since: Fri , 14 May 2021 17:23:13 GMT
Etag
-
Etag
Etag 首部字段用于代表资源的唯一性标识,服务器会按照指定的规则生成资源的标识,其属于响应首部字段
当资源发生变化时,Etag 的标识也会更新。同样的,当浏览器第一次接收到服务器返回资源的 Etag 值后,其会把这个值存储起来 -
If-None-Match
并在下次访问该资源时通过携带 If-None-Match 请求首部发送给服务器验证该资源有没有过期
如果服务器发现 If-None-Match 值与 Etag 不一致时,说明服务器上的文件已经被更新,那么服务器会发送更新后的资源给浏览器并返回最新的 Etag 值,浏览器收到资源后会更新缓存的 If-None-Match 的值