HTTP 缓存=“先看本地冰箱够不够新鲜(强缓存);不够再打电话问超市要不要换(协商缓存)”。服务器判断是否过期靠 Expires / Cache-Control 给出的“保质期”,以及 ETag / Last-Modified 做“指纹校验”。
一、缓存流程图解(关键决策链)
二、服务器判断缓存过期的核心机制
1. 强缓存阶段(无需询问服务器)
-
Cache-Control 响应头(优先级最高):
Cache-Control: max-age=3600 // 资源有效期3600秒(1小时)
-
max-age=[秒]:资源有效期(从请求时间开始计算)
-
s-maxage=[秒]:仅对公共代理缓存有效(CDN专用)
-
no-store:禁止任何缓存(敏感数据场景)
-
no-cache:跳过强缓存,直接进入协商缓存
-
public:允许任何缓存方(浏览器/CDN)存储
-
private:仅允许用户浏览器缓存(禁止CDN)
-
-
Expires 响应头(HTTP/1.0遗留):
Expires: Wed, 24 Jul 2024 08:30:00 GMT // 绝对过期时间
-
缺陷:依赖客户端时钟同步,已被 Cache-Control 取代
-
2. 协商缓存阶段(需向服务器验证)
当强缓存失效时,客户端携带验证头发起条件请求:
-
Last-Modified + If-Modified-Since
# 响应头(服务器返回)
Last-Modified: Wed, 17 Jul 2024 12:00:00 GMT
# 请求头(客户端后续携带)
If-Modified-Since: Wed, 17 Jul 2024 12:00:00 GMT-
服务器对比当前资源的修改时间
-
问题:1秒精度不足,文件内容不变但修改时间可能变化
-
-
ETag + If-None-Match(优先级更高)
# 响应头(服务器返回)
ETag: "33a64df551425fcc55e4d42a148795d9"
# 请求头(客户端后续携带)
If-None-Match: "33a64df551425fcc55e4d42a148795d9"-
ETag 是资源内容的哈希值(如MD5)
-
内容变化时 ETag 必变,精确判断内容变更
-
分强弱验证:
-
强ETag:字节级匹配("xyz")
-
弱ETag:内容语义匹配(W/"xyz",前缀 W/)
-
-
三、缓存决策关键头组合示例
场景1:静态资源(JS/CSS)长期缓存
HTTP/1.1 200 OK
Cache-Control: public, max-age=31536000 // 1年有效期
ETag: "fd562e25w5e41"
场景2:用户私密数据
HTTP/1.1 200 OK
Cache-Control: private, no-cache // 仅浏览器缓存且跳过强缓存
场景3:频繁变化的API数据
HTTP/1.1 200 OK
Cache-Control: no-cache // 强制每次协商验证
ETag: "a3f5gd8e9k2"
四、缓存生效全流程演示
首次请求
GET /app.js HTTP/1.1 HTTP/1.1 200 OK
Cache-Control: max-age=3600
ETag: "abc123"
Last-Modified: Wed, 24 Jul 2024 00:00:00 GMT
60分钟内再次请求 → 直接读浏览器缓存(不发送请求)
60分钟后请求(强缓存过期)
GET /app.js HTTP/1.1
If-Modified-Since: Wed, 24 Jul 2024 00:00:00 GMT
If-None-Match: "abc123"
-
若资源未变 → 返回 304 Not Modified,重置缓存有效期
-
若资源变化 → 返回 200 OK 和新内容
五、缓存陷阱与解决方案
用户看不到更新 | 强缓存未过期 | 文件名添加哈希:app.a3c4.js |
CDN不更新 | 源服务器未刷新CDN缓存 | 添加 Cache-Control: s-maxage=0 |
登录态与缓存冲突 | 缓存了用户私有数据 | 设置 Cache-Control: private |
弱网环境缓存失效 | 未正确配置 Cache-Control | 至少设置 max-age=600(10分钟) |
六、最佳实践策略
静态资源
-
文件名带内容哈希:/css/style.a3d8.css
-
设置超长缓存:Cache-Control: public, max-age=31536000
动态API
-
短缓存 + 协商缓存:
Cache-Control: no-cache, max-age=600 // 10分钟强缓存 + 强制验证
ETag: "x138de9"
HTML入口文件
-
禁止缓存(确保版本更新):
Cache-Control: no-store, no-cache, must-revalidate
📊 性能收益:合理缓存可使重复访问速度提升 300%+(HTTP Archive 数据)
七、调试技巧(Chrome DevTools)
Network面板
-
尺寸列显示 (from disk cache) 表示强缓存命中
-
304 状态码表示协商缓存生效
查看完整缓存头 https://example.com/chrome-cache-headers.png
强制刷新
-
Ctrl+F5:忽略强缓存(带 Cache-Control: no-cache 头)
-
Ctrl+Shift+R:忽略所有缓存和Service Worker
缓存配置口诀:
静态资源长缓存,动态数据短校验, 哈希指纹破更新,HTML入口永不存。
评论前必须登录!
注册