FORMA
博客 / 教程
教程 · 阅读约 3 分钟 · 24 次阅读 · 发布于 2026-09-27 · FORMA 团队

HTTP 缓存实战:从强缓存到协商缓存

Cache-Control 到底怎么配?为什么改了代码用户还是看到旧页面?这篇按真实排查思路讲。

「我明明发了新版,为什么用户看到的是旧的?」——十有八九是缓存头没配对。HTTP 缓存不复杂,核心就是两套机制:强缓存(不发请求直接用本地)和协商缓存(发请求问服务器有没有变)。配错任何一个,要么更新不生效,要么白走流量。

强缓存:Cache-Control 与 Expires

Cache-Control 是现在的标准,Expires 是老式日期写法,两者同时存在以前者为准。常用的几个值:

典型配置:

# HTML:短缓存,保证更新及时
Cache-Control: public, max-age=3600

# 带指纹的静态资源:一年强缓存
Cache-Control: public, max-age=31536000, immutable

带哈希文件名的资源(app.a1b2c3.js)内容变了文件名必变,可以大胆给一年;HTML 文件名不变,必须短缓存,否则发布新版用户看不到。

协商缓存:ETag 与 Last-Modified

强缓存过期后,浏览器带着凭证去问服务器。两种凭证:

响应流程:

首次请求 → 200,响应带 ETag: "abc123"
再次请求 → 请求头带 If-None-Match: "abc123"
内容未变 → 304,无响应体,省掉整份传输
内容已变 → 200 + 新 ETag

ETag 优先;自建服务器(Nginx)对静态文件默认两者都开,不用手工配。

缓存层级:浏览器、CDN、服务端

一次请求可能穿过好几层缓存:

1. 浏览器内存缓存(最快,关掉标签页就没了) 2. 浏览器磁盘缓存 3. CDN 边缘节点 4. 源站反向代理(Nginx 的 proxy_cache) 5. 应用本身

排查「用户看到旧页面」时,从上往下逐层确认:Ctrl+Shift+R 强刷能好,是 1-2 层;换网络/IP 能好,是 CDN;怎么都不好,是源站缓存或应用输出缓存。

实战:发布新版本不失效、不陈旧

location ~* \.(js|css|png|webp|woff2)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}
location ~* \.html$ {
    expires 1h;
}

三个高频踩坑

一句话总结:带哈希的资源往死里缓存,不带哈希的短缓存或协商缓存;发布链路里每一层缓存都要知道它存在、知道怎么清。

评论 · 0 条

还没有评论,来抢沙发。

评论经人工审核后公开;请勿提交密码、密钥等敏感信息。