缓存机制
Roger Leung ( z3rog ) 2019-07-01 ChromeHTTP
本文结合浏览器、HTTP 协议聊聊缓存机制
# 流程
- 浏览器请求
- 无缓存?
- 向服务器请求
- 请求响应,缓存协商
- 页面响应
# 两种缓存机制
# 强制缓存
所谓强制缓存,是指服务器指定一个缓存时间,在缓存时间内的请求直接用缓存,不在时间内再执行比较缓存。通常有两种形式:
- 设置
Expires: <http-date>
的响应头,指定一个到期时间(见MDN (opens new window)) - 设置
Cache-Control
头,指定max-age
或s-maxage
(单位均为秒,后者会覆盖前者,但基本只在代理服务器中生效),例子:Cache-Control: max-age=604800
若 Cache-Control 设置了 max-age / s-maxage 优先级会高于 Expires。
Cache-Control 还有更多用法,见 MDN (opens new window)
# 对比缓存
# Etag / If-None-Match 策略
- Etag:服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识,生成规则由服务器决定,通常是 MD5。
- If-None-Match:当资源过期时,检查是否有 Etag,若有,则再次向服务器请求时带上 If-None-Match:Etag 值。服务器收到请求后若判断到有 If-None-Match 的请求头,则与被请求资源以原来生成 Etag 时相似的规则进行比对。若字符串匹配,说明服务端响应资源没有更新,返回 304 让浏览器直接使用缓存(响应中只有状态行与头,不含响应体);若不匹配,则携带新的资源作为响应体,返回 200,重新执行缓存协商。
# Last-Modified / If-Modified-Since 策略
- Last-Modified:当没有 Etag 时,检查是否有该头。该头表明上一次请求时存下来的文件最后修改时间。
- If-Modified-Since:通过该头将 Last-Modified 的时间请求到服务器,与 Etag 策略类似,让服务器来判断文件是否被修改。只不过这次的比较不使用 MD5,而是使用时间。步骤与 Etag 策略相同。
通常为了保险,多个响应头标识会同时使用,防止缓存失效。
# 两种缓存的生效与失效
# 均生效
- 地址栏输入链接
- 通过其他网页跳转
- 开启新窗口打开同样的页面
- 浏览器前进后退按钮
# 强制缓存失效
- 按 F5 刷新
# 均失效
- 清空缓存并硬性刷新(Mac 下的 ⌘ + ⇧ + R)