
当网站更新了 CSS 或 JS 文件,用户浏览器却还在用旧版本,通常是因为 Nginx 默认缓存策略太“保守”——静态资源被长期缓存,且未随文件内容变化而失效。解决核心在于:让浏览器缓存资源,但确保文件内容一变,URL 或响应头就变,从而绕过旧缓存。
启用基于文件内容的版本化 URL(推荐)
最可靠的方式是构建时生成带哈希值的文件名(如 main.a1b2c3d4.js),再在 HTML 中引用该带哈希的路径。这样每次内容变更,文件名就不同,浏览器自然视为新资源,无需清理旧缓存。
前端构建工具(Webpack/Vite/ESBuild)默认支持输出带 contenthash 的文件名 Nginx 不需要特殊配置,只需正常提供这些静态文件即可 HTML 中通过构建插件自动注入正确路径(如 HtmlWebpackPlugin)
配置合理的 Cache-Control 与 ETag
对未做哈希命名的资源(如开发阶段或遗留系统),需靠响应头控制缓存行为。Nginx 可主动设置 Cache-Control 并启用 ETag,让浏览器在文件变更后发起条件请求(If-None-Match)并收到 304 响应。
在 server 或 location 块中添加:add_header Cache-Control "public, max-age=31536000, immutable";(适用于带哈希的文件) 对未哈希的 CSS/JS,建议:add_header Cache-Control "public, max-age=3600, must-revalidate"; 确保 etag on; 已开启(Nginx 默认开启),配合 if_modified_since exact; 可提升 304 判断准确性
避免暴力禁用缓存(不推荐)
有些方案直接设 Cache-Control: no-cache 或 max-age=0,看似“每次都拉新”,实则牺牲性能:每次请求仍要走完整 HTTP 流程(DNS、TCP、TLS、HEAD 请求验证),反而拖慢页面加载。
立即学习“前端免费学习笔记(深入)”;
不建议在生产环境对 CSS/JS 使用 no-store 或频繁 no-cache 开发调试阶段可用 expires -1; 临时关闭缓存,上线前务必改回合理策略 若必须强制刷新,应由前端控制(如加时间戳参数 ?v=20240520),但该方式易被代理忽略,不如哈希可靠
验证缓存行为是否生效
部署后务必检查实际响应头,不能只信配置。打开浏览器开发者工具 → Network → 刷新页面 → 点击一个 .css 或 .js 文件 → 查看 Response Headers 中的 Cache-Control、ETag、Last-Modified 是否符合预期。
带哈希的文件应返回 immutable 和超长 max-age 普通静态文件应有 ETag 且第二次加载状态码为 304 用 curl -I https://yoursite.com/style.css 可快速查看响应头

评论(0)