JavaScript长期强缓存需Nginx配置Cache-Control: public, max-age=31536000, immutable并匹配带6位以上哈希的JS文件名(如app.a1b2c3.js),HTML必须禁用缓存且与JS策略解耦,部署后须验证响应头、缓存命中及404清理。

JavaScript 文件的长期强缓存,不是在 JS 代码里写配置,而是靠 Nginx 在响应头中正确设置 Cache-Control 和 Expires,并严格匹配前端构建产物的稳定性特征。核心前提是:JS 文件名必须带内容哈希(如 app.a1b2c3.js),否则缓存再久也收不到更新。
只对带哈希的 JS 文件启用长期缓存
Nginx 不识别哈希值本身,但可通过正则精准匹配含哈希特征的文件名,避免误缓存无版本控制的通用脚本:
- 推荐用后缀 + 哈希长度组合匹配,例如:
location ~* "\.[a-f0-9]{6,}\.js$"(匹配至少6位十六进制哈希的 .js 文件) - 不建议仅靠
\.js$全局匹配,否则vendor.js或polyfill.js等无哈希文件也会被设为 1 年缓存,导致发版失效 - 若构建工具输出统一带哈希(如 Vite 默认开启
build.rollupOptions.output.entryFileNames配置),可简化为后缀匹配,但仍需确保路径下无非哈希 JS
响应头必须包含 immutable + max-age=31536000
单设 max-age=31536000 只是“一年内可缓存”,用户手动刷新时浏览器仍会发 If-None-Match 请求验证;加上 immutable 才真正跳过所有验证:
- 完整头部示例:
add_header Cache-Control "public, max-age=31536000, immutable" always; -
always参数确保即使返回 304 或 4xx 状态码,该头也生效(防止某些错误场景漏加) - 无需单独配
expires 1y——max-age已覆盖其作用;若保留,需保证两者时间一致,否则可能引发兼容性歧义
HTML 入口必须与 JS 缓存策略解耦
JS 缓存再激进,如果 HTML 还在用户本地缓着旧版本,新 JS 根本不会被加载。入口页必须走完全不同的策略:
立即学习“Java免费学习笔记(深入)”;
- 匹配所有 HTML:
location ~* \.html$ { expires -1; add_header Cache-Control "no-cache, must-revalidate, max-age=0"; } - 确保 Nginx 开启 ETag(默认已开),让浏览器能发起条件请求;服务端返回 304 时,HTML 不重载,但 JS 路径已更新,新资源自然拉取
- 禁用
immutable于 HTML —— 它的内容随时变化,声明“不可变”违反语义,部分浏览器会忽略缓存头
上线后必须验证三处关键状态
配置写完不等于生效。每次部署后应快速确认:
- 用
curl -I https://your.site/js/app.a1b2c3.js检查响应头是否含Cache-Control: public, max-age=31536000, immutable - Chrome DevTools → Network → 刷新页面,找该 JS 文件:状态显示 200 (from disk cache) 才算强缓存命中;若为 304,说明
immutable未生效或文件名没哈希 - 故意修改 JS 内容、重新构建、部署,观察新哈希文件是否被加载,且旧哈希 URL 访问返回 404(证明路径收敛,无残留缓存干扰)


















