html文件必须设为no-cache或max-age=0,must-revalidate,因其作为动态入口不可长期缓存;静态资源需文件名哈希+immutable长期缓存;cdn策略须与源站响应头一致;meta标签对缓存无效。

HTML 文件必须设 no-cache 或 max-age=0, must-revalidate
HTML 是页面的“入口”和状态枢纽,哪怕只改了一个按钮文案、一个 CSRF token、一个时间戳,旧缓存就会导致功能异常。浏览器一旦走强缓存(比如 max-age=3600),就完全跳过服务器验证——而 HTML 很少配 ETag 或 Last-Modified 做兜底,用户可能卡在旧页一小时。
正确做法是让服务端对所有 HTML 响应返回:
-
Cache-Control: no-cache, must-revalidate:允许缓存,但每次必须向服务端发验证请求(带If-None-Match) - 或更明确的
Cache-Control: max-age=0, must-revalidate:兼容性略好,语义更直白 - 绝对不要用
private:CDN 节点会忽略它,导致边缘缓存失效 - 禁用
no-store:它连内存缓存都禁了,首屏性能受损,且对 HTML 来说没必要
静态资源要用内容哈希 + immutable 实现长期缓存
CSS、JS、图片这些资源本身不变,变的是文件内容。所以不能靠时间控制缓存,而要靠 URL 变化触发新拉取。
构建时生成带哈希的文件名(如 main.a1b2c3.js),再配合响应头:
Cache-Control: public, max-age=31536000, immutable-
ETag开启(作为 fallback,防误覆盖) -
if_modified_since exact(Nginx 中启用精确比对)
immutable 指令告诉 Chrome 等浏览器:只要 URL 没变,就别发条件请求(省掉一次 If-None-Match 往返),但前提是 HTML 本身不被长缓存——否则用户拿到旧 HTML,引用的还是旧哈希路径。
CDN 缓存策略必须和服务端响应头严格一致
CDN 不是缓存“开关”,而是缓存“放大器”。如果源站返回 Cache-Control: no-cache,但 CDN 后台又单独配置了 /index.html 缓存 10 分钟,那用户看到的就是 CDN 缓存的旧 HTML,哪怕源站早更新了。
调试时重点看两个头:
- Network 面板里 HTML 请求的
Response Headers→ 确认Cache-Control是否为no-cache - 同个请求的
x-cache(Cloudflare)或x-cdn-cache(阿里云)→ 看是否命中 CDN,以及是否被覆盖 - CDN 控制台里,
/index.html这类路径必须设为“绕过缓存”或“缓存 TTL = 60s”,不能依赖默认策略
<meta http-equiv> 对缓存完全无效,别写
现代浏览器(Chrome/Firefox/Safari/Edge)全部忽略 <meta http-equiv="Cache-Control"> 和 <meta http-equiv="Expires">。它既不参与 HTTP 请求流程,也不触发任何协商校验。
唯一“看起来生效”的情况,只是巧合:
- 你写了
<meta http-equiv="refresh" content="0">—— 这是重定向,不是缓存控制 - 本地用
file://协议打开 HTML —— 根本没 HTTP 头,谈不上缓存逻辑 - 开发者工具里勾了 “Disable cache” —— 这是人为干预,掩盖真实配置问题
缓存行为只由服务端响应头决定。写 meta 标签只会让你误以为“已处理”,结果上线后用户集体卡在旧版本。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











