Cache Control 之 must-revalidate
启发式缓存
想让一个资源能缓存,有三种方式,按照解析优先级排序如下:
- HTTP 1.1 风格的
Cache-Control
响应头中的max-age
指令 - HTTP 1.0 风格的
Expires
响应头 Last-Modified
响应头
HTTP/2 200
Date: Wed, 27 Mar 2019 22:00:00 GMT
Last-Modified: Wed, 27 Mar 2019 12:00:00 GMT
没有Cache-Control
,也没有 Expires
,但它其实也可以被缓存。
启发式缓存:可缓存时长是用 Date
响应头的时间减去Last-Modified
的时间,得出的时长再除以10
,用汉语描述的话,就是用这个文件最近一次更新到现在的十分之一时长作为可缓存时长,这个例子的话,计算出的可缓存时长是一小时。
规范中仅仅是推荐而已,并没有做强制要求,比如 Firefox 中就在这个算法的基础上还和 7 天时长取了一次最小值,是 min(one-week, (date_value - last_modified_value) * 0.10)
。
如果你想禁用由 Last-Modified
响应头造成的启发式缓存,正确的做法是要加上 Cache-Control: no-cache
,但在 Chrome 中,Cache-Control: must-revalidate
也有同样的功效。但这并不是正规作用
must-revalidate
revalidate
:指的是当的客户端缓存过期的时候,向服务端发送条件请求,检查缓存资源是否仍然可用的过程。
客户端:浏览器/缓存服务器
服务端:源站/缓存服务器
条件请求:带有If-Modified-Since
/If-None-Match
请求头的请求
must-revalidate
指令是用来表示在一个缓存过期之后,不能直接使用这个过期的缓存,必须校验之后才能使用。
must-revalidate
生效的场景还有一个大前提,那就是 HTTP 规范是允许客户端在某些特殊情况下直接使用过期缓存的,比如校验请求发送失败的时候,还比如有配置一些特殊指令(stale-while-revalidate
、stale-if-error
等)的时候;带有 must-revalidate
的缓存,在任何情况下,都必须成功 revalidate 后才能使用,没有例外。
参考