一、HTTP 缓存的分类
HTTP 缓存主要分为两类:
强缓存(Strong Cache)
浏览器在命中强缓存时,不会向服务器发送请求,直接使用本地缓存资源。
控制字段主要有:Cache-Control(HTTP/1.1):优先级更高,常用指令包括:max-age=3600:资源在 3600 秒内有效no-cache:跳过强缓存,但会进行协商缓存no-store:禁止缓存public/private:是否可被共享缓存(如 CDN)存储
Expires(HTTP/1.0):指定一个绝对过期时间(如Expires: Wed, 21 Oct 2025 07:28:00 GMT),但受客户端时间影响,已被Cache-Control取代。
协商缓存(Revalidation / Weak Cache)
当强缓存失效后,浏览器会携带缓存标识向服务器验证资源是否更新。若未更新,服务器返回304 Not Modified,浏览器继续使用本地缓存;否则返回新资源(200)。
主要通过以下头部实现:Last-Modified+If-Modified-Since:基于文件最后修改时间ETag+If-None-Match:基于资源内容生成的唯一标识(更精确,优先级高于 Last-Modified)
注意:
Cache-Control: no-cache并不是“不缓存”,而是跳过强缓存,强制走协商缓存;而no-store才是完全禁止缓存。
二、缓存决策流程(简化版)
- 浏览器发起请求;
- 检查是否存在强缓存(
Cache-Control或Expires):- 若未过期 → 直接使用缓存(状态码 200 from disk/memory cache);
- 若已过期或无强缓存 → 进入协商缓存;
- 发送带
If-None-Match或If-Modified-Since的请求到服务器; - 服务器比对后:
- 资源未变 → 返回 304,浏览器用缓存;
- 资源已变 → 返回 200 + 新资源。
三、实际开发中的最佳实践
静态资源(JS/CSS/图片等):
使用Cache-Control: max-age=31536000(一年),并配合文件名哈希(如 bundle.a1b2c3.js)实现“永久缓存 + 内容更新即换名”。HTML 文件:
通常设为Cache-Control: no-cache,确保每次都能获取最新入口,避免因缓存导致新版本无法加载。API 接口数据:
一般不缓存(no-store)或短时间协商缓存,防止数据陈旧。CDN 场景:
注意Cache-Control中public与private的区别,敏感数据应设为private,避免被中间代理缓存。
四、调试技巧
- Chrome DevTools → Network 面板:
Size列显示(memory cache)/(disk cache)表示命中强缓存;- 状态码
304表示协商缓存命中; - 勾选Disable cache可临时禁用缓存(仅开发者工具打开时生效)。
总结
HTTP 缓存机制是性能优化的基石。合理配置Cache-Control、ETag等头部,结合构建工具的文件指纹策略,可以在保证内容实时性的同时最大化缓存收益。