# http缓存
# 强缓存
不需要向服务器发送请求,读取浏览器本地缓存,HTTP状态码是200,由三个属性控制 Expires、Cache-Control 和 Pragma
Pragma
- Pragma 只有一个属性值,就是 no-cache ,效果和 Cache-Control 中的 no-cache 一致,不使用强缓存,需要与服务器验证缓存是否新鲜,在 3 个头部属性中的优先级最高。
Cache-Control
- max-age:单位是秒,缓存时间计算的方式是距离发起的时间的秒数,超过间隔的秒数缓存失效
- no-cache:不使用强缓存,需要与服务器验证缓存是否新鲜
- no-store:禁止使用缓存(包括协商缓存),每次都向服务器请求最新的资源
- private:专用于个人的缓存,中间代理、CDN 等不能缓存此响应
- public:响应可以被中间代理、CDN 等缓存
- must-revalidate:在缓存过期前可以使用,过期后必须向服务器验证
Expires
- 是一个HTTP日期,发起请求时会根据系统时间个Expire对比,优先级最低,会存在本地时间和服务器时间不一致情况。
# 协商缓存
先去服务器验证缓存是否过期,过期则重新请求,否则HTTP状态码返回304并且设置Last-Modified或者Etag属性。
- Etag/If-None-Match
- 用一串hash码代表资源的标识符,文件发生变化才会改变hash码。通过If-None-Match 和 文件的hash比较一样则命中缓存。
- Last-Modified/If-Modified-Since
- 值代表文件最后修改的时间,第一次会把文件修改的时间放到Last-Modified,第二次发起请求的时候,请求头会带上上一次响应头中的 Last-Modified 的时间,并放到 If-Modified-Since 请求头属性中,服务端根据文件最后一次修改时间和 If-Modified-Since 的值进行比较,如果相等,返回 304 ,并加载浏览器缓存。
ETag/If-None-Match 的出现主要解决了 Last-Modified/If-Modified-Since 所解决不了的问题:
- 如果文件的修改频率在秒级以下,Last-Modified/If-Modified-Since 会错误地返回 304
- 如果文件被修改了,但是内容没有任何变化的时候,Last-Modified/If-Modified-Since 会错误地返回 304 ,上面的例子就说明了这个问题