返回文章列表
·1 分钟阅读·

Cache Control 之 must-revalidate

启发式缓存

想让一个资源能缓存,有三种方式,按照解析优先级排序如下:

  1. HTTP 1.1 风格的Cache-Control  响应头中的  max-age指令
  2. HTTP 1.0 风格的  Expires  响应头
  3. 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-revalidatestale-if-error等)的时候;带有  must-revalidate  的缓存,在任何情况下,都必须成功 revalidate 后才能使用,没有例外。

参考

  1. 可能是最被误用的 HTTP 响应头之一 Cache-Control: must-revalidate - 知乎