写在前面的总结

  • 缓存是浏览器的功能
  • 浏览器通过在请求时检查 Headers 里面的 缓存相关的key判断是否有缓存
  • 浏览器可以通过 cache-control / expires / pragma 确认是否为强缓存,如果是且需要通过检查各个值判断强缓存内容是否过期,如果过期了,请求继续往服务器发送
  • 接上,请求到达服务器后,如果请求头中还存在这 If-None-Match (来源上次请求返回的Etag)或者 If-Modified-Since(来源上次相同请求返回的Last-Modified) ,由服务端判断缓存是否生效,是返回304用缓存(这个又叫协商缓存)
  • 接上,没有继续向真实的服务去获取新数据

image.png

image.png

image.png

强缓存

如果响应头中expirespragma或者cache-control字段,代表这是强缓存,浏览器就会把资源缓存在memory cache 或 disk cache中。第二次请求时,浏览器判断请求参数,如果符合强缓存条件就直接返回状态码200,从本地缓存中拿数据。否则把响应参数存在request header请求头中,看是否符合协商缓存,符合则返回状态码304,不符合则服务器会返回全新资源。

tips: 强缓存の状态码 200;协商缓存の状态码:304

1
2
3
<meta http-equiv="cache-control" content="no-cache,private,no-store" />
<meta http-equiv="expires" content="3600" />
<meta http-equiv="pragma" content="no-cache" />

设置项

1. cache-control

MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control

请求指令

1
2
3
4
5
6
7
Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: only-if-cached

缓存响应指令

1
2
3
4
5
6
7
8
9
Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>

扩展Cache-Control指令

1
2
3
4
5
// 拓展缓存指令不是核心HTTP缓存标准文档的一部分,使用前请注意检查兼容性!

Cache-control: immutable
Cache-control: stale-while-revalidate=<seconds>
Cache-control: stale-if-error=<seconds>

指令

可缓存性

public

表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存,即使是通常不可缓存的内容。(例如:1.该响应没有max-age指令或Expires消息头;2. 该响应对应的请求方法是 POST 。)

private

表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容,比如:对应用户的本地浏览器。

no-cache

在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。

no-store

缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。

到期

max-age=

设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。

s-maxage=

覆盖max-age或者Expires头,但是仅适用于共享缓存(比如各个代理),私有缓存会忽略它。

max-stale[=]

表明客户端愿意接收一个已经过期的资源。可以设置一个可选的秒数,表示响应不能已经过时超过该给定的时间。

min-fresh=

表示客户端希望获取一个能在指定的秒数内保持其最新状态的响应。

stale-while-revalidate= Experimental

表明客户端愿意接受陈旧的响应,同时在后台异步检查新的响应。秒值指示客户愿意接受陈旧响应的时间长度。

stale-if-error= Experimental

表示如果新的检查失败,则客户愿意接受陈旧的响应。秒数值表示客户在初始到期后愿意接受陈旧响应的时间。

重新验证和重新加载

must-revalidate

一旦资源过期(比如已经超过max-age),在成功向原始服务器验证之前,缓存不能用该资源响应后续请求。

proxy-revalidate

与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。

immutable Experimental

表示响应正文不会随时间而改变。资源(如果未过期)在服务器上不发生改变,因此客户端不应发送重新验证请求头(例如If-None-Match或If-Modified-Since)来检查更新,即使用户显式地刷新页面。在Firefox中,immutable只能被用在 https:// transactions. 有关更多信息,请参阅这里

其他

no-transform

不得对资源进行转换或转变。Content-Encoding、Content-Range、Content-Type等HTTP头不能由代理修改。例如,非透明代理或者如Google’s Light Mode可能对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。no-transform指令不允许这样做。

only-if-cached

表明客户端只接受已缓存的响应,并且不要向原始服务器检查是否有更新的拷贝

expires

是HTTP1.0控制网页缓存的字段,值为一个时间戳,准确来讲是格林尼治时间,服务器返回该请求结果缓存的到期时间,意思是,再次发送请求时,如果未超过过期时间,直接使用该缓存,如果过期了则重新请求。
有个缺点,就是它判断是否过期是用本地时间来判断的,本地时间是可以自己修改的。

pragma

这个是HTTP1.0中禁用网页缓存的字段,其取值为no-cache,和Cache-Control的no-cache效果一样