html必须短缓存,因其作为spa入口决定js/css哈希路径;若强缓存则浏览器不发起请求,新资源永远无法加载,导致白屏或功能异常。

单独在 HTML 里加 meta 标签或手动改 src 路径,无法解决哈希资源更新失败的问题——浏览器根本不读 meta http-equiv="Cache-Control",而 HTML 文件一旦被强缓存,就再也不会重新请求,新 JS/CSS 的哈希名永远进不来。
为什么 HTML 文件必须短缓存
SPA 的入口 HTML(如 index.html)本质是“资源调度器”:它决定加载哪个带哈希的 JS/CSS。如果服务器返回 Cache-Control: public, max-age=31536000,浏览器会直接从磁盘读取旧 HTML,连请求都不发,自然不会拿到新哈希对应的资源路径。
- 常见错误现象:
Network面板中index.html显示200 (from disk cache),但页面功能异常或白屏 - Vue CLI / Create React App 默认开发服务器对
index.html启用内存缓存,改完不重启服务,本地也看不到效果 - 生产环境必须设为
Cache-Control: no-cache, must-revalidate或max-age=0,强制每次校验 ETag/Last-Modified - Nginx 示例配置:
location = /index.html { add_header Cache-Control "no-cache, must-revalidate"; }
静态资源(JS/CSS/图片)必须带内容哈希且配 immutable
光给文件名加哈希(如 app.a1b2c3.js)不够,服务端响应头没配对,浏览器仍可能复用旧缓存——尤其当用户刷新时,若没触发协商缓存,immutable 就能避免重复验证。
- Webpack/Vite 构建产物默认生成哈希文件名,但需确认输出配置启用
contenthash(非hash或chunkhash),否则内容不变时哈希也可能变 - 服务端必须返回
Cache-Control: public, immutable, max-age=31536000,immutable告诉浏览器:只要 URL 不变,资源内容就绝不会变,不用再发条件请求 - 若服务端不支持
immutable(如老旧 CDN),至少要确保ETag正确且与文件内容强绑定,否则协商缓存失效 - 错误配置示例:
Cache-Control: public, max-age=31536000(缺immutable)→ 浏览器在后续请求中仍可能发If-None-Match,而服务端若 ETag 计算错,就返回 200 而非 304,导致重复下载
Service Worker 和 Cache Storage 是隐藏缓存杀手
哪怕你把 HTML 缓存策略调得再准,一旦注册了 Service Worker 并预缓存了 index.html 或资源列表,Ctrl+F5 和 Disable cache 全部失效——请求根本到不了网络层,直接从 Cache Storage 返回旧副本。
- Workbox 默认预缓存
index.html,更新后必须触发 SW 更新逻辑(如修改sw.js内容、调用skipWaiting()+clients.claim()) - Chrome 中彻底清理:
chrome://settings/siteData→ 搜索域名 → 点击右侧三点 → “移除”,确保Cache Storage、Service Workers、Local Storage全部清空 - 开发阶段建议:在
navigator.serviceWorker.register()后加console.log('SW registered:', registration.active?.scriptURL),确认注册的是最新版本 - 不要依赖
console.clear()或刷新 DevTools —— 它对已激活的 SW 无影响
CDN 和反向代理缓存常被忽略
前端构建和服务器响应头都配对了,用户还是看到旧 HTML?大概率是 CDN(Cloudflare / Nginx proxy_cache)把 index.html 缓存了数小时甚至数天,且默认忽略查询参数(?v=xxx)。
- Cloudflare Page Rules 示例:
/*→ 设置缓存级别为Bypass;或针对/index.html单独设为Standard并将缓存 TTL 改为1 hour - Nginx 反向代理中,若用了
proxy_cache,必须排除 HTML:location ~* \.html$ { proxy_cache_bypass 1; proxy_no_cache 1; } - 临时验证是否 CDN 拦截:curl -I https://yoursite.com/index.html,检查
X-Cache或CF-Cache-Status响应头 - 上线前务必在 CDN 控制台提交
index.html的缓存刷新请求,不能只等 TTL 过期
最稳的更新链路不是靠“清缓存”,而是让浏览器无法复用旧资源:HTML 短缓存 + JS/CSS 带内容哈希 + 服务端配 immutable + SW 主动更新 + CDN 显式绕过。漏掉任意一环,用户就可能卡在某个旧版本里不动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











