彻底搞懂 HTTP 缓存:强缓存与协商缓存
HTTP 缓存是提升网页加载速度最廉价的手段之一。合理的缓存策略可以让重复访问几乎不产生网络请求,而错误的策略则会让用户迟迟看不到新版本。本文梳理浏览器缓存的完整决策过程。
一、两类缓存
浏览器缓存分为两个阶段:
- 强缓存:在有效期内直接使用本地副本,不发请求,状态显示为
200 (from disk cache)或(from memory cache)。 - 协商缓存:强缓存过期后,带上校验信息询问服务器“资源变了吗?”,没变则返回
304 Not Modified,只传响应头。
二、强缓存:Cache-Control
Cache-Control 是 HTTP/1.1 的标准方案,优先级高于旧的 Expires。常用指令:
Cache-Control: max-age=31536000, immutable # 一年内直接用本地缓存
Cache-Control: no-cache # 可以缓存,但每次使用前必须向服务器验证
Cache-Control: no-store # 完全不缓存
Cache-Control: private # 只允许浏览器缓存,CDN 等代理不缓存
注意:no-cache并不是“不缓存”,而是“每次都要协商”。真正的不缓存是no-store。
三、协商缓存:ETag 与 Last-Modified
服务器在首次响应时返回校验字段,浏览器在后续请求中带回:
# 首次响应
ETag: "5f3a-1a2b3c"
Last-Modified: Mon, 28 Sep 2026 08:00:00 GMT
# 再次请求
If-None-Match: "5f3a-1a2b3c"
If-Modified-Since: Mon, 28 Sep 2026 08:00:00 GMT
ETag 基于内容生成,精度更高,同时存在时优先使用。Last-Modified 只精确到秒,且文件被“touch”但内容未变时也会失效。
四、静态资源的最佳实践
现代前端构建工具会给产物文件名加上内容哈希,例如 app.3f9a1c.js。据此可以采用“两段式”策略:
- HTML 入口:
Cache-Control: no-cache,保证每次都能拿到最新的资源引用。 - 带哈希的 JS/CSS/图片:
Cache-Control: max-age=31536000, immutable,内容变了文件名就变,永远不用担心过期。
这样既让用户第一时间看到新版本,又让未变化的资源完全命中本地缓存。
小结
记住一句话:先看强缓存是否有效,无效再协商;HTML 不强缓存,哈希资源长缓存。
← 返回首页