Vue.js SPA部署:如何缓存JS/CSS但禁止index.html缓存?
解决index.html缓存导致静态资源更新不生效的问题
这问题我帮不少团队排查过,核心就是别给所有资源搞一刀切的缓存策略,得给index.html和版本化的JS/CSS文件分别配置不同的HTTP缓存规则——你之前遇到所有资源都无法缓存的问题,肯定是把无缓存头全局应用了,没做路径匹配。
明确目标缓存策略
先把我们要的效果拆清楚:
- index.html:强制浏览器每次请求都跟服务器校验(或者直接不缓存),确保新版本发布后,用户能拿到最新的资源引用路径
- JS/CSS(版本化文件):允许长期缓存,因为你已经做了版本化(文件名带哈希/版本号),只要内容更新文件名就会变,完全不用担心缓存过期的问题
具体配置方案
1. 给index.html设置专属缓存头
只对index.html应用以下缓存规则,绝对不要全局配置:
Cache-Control: max-age=0, must-revalidate:告诉浏览器这个资源的缓存有效期为0,每次请求都必须去服务器验证是否有更新- 兼容旧浏览器可以额外加上
Pragma: no-cache和Expires: 0
举个Nginx的配置示例(其他服务器如Apache、CDN同理,核心是精确匹配index.html路径):
# 精确匹配根目录的index.html,应用强制校验规则 location = /index.html { add_header Cache-Control "max-age=0, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; }
2. 给版本化JS/CSS设置长期缓存
对所有带版本号的JS/CSS文件,设置长期缓存规则:
Cache-Control: public, max-age=31536000, immutable:public允许CDN和浏览器缓存,max-age=31536000是一年有效期,immutable告诉浏览器在有效期内不用再发请求验证(因为文件名变了才会有新资源)
同样用Nginx示例:
# 匹配所有JS/CSS文件,应用长期缓存 location ~* \.(js|css)$ { add_header Cache-Control "public, max-age=31536000, immutable"; # 可选:如果需要,可以添加ETag或Last-Modified作为 fallback,但版本化文件名已经足够 }
关键注意事项
- 确保版本化文件名正确生成:用Webpack、Vite等构建工具时,要开启内容哈希(contenthash/chunkhash),确保文件内容变化时文件名自动更新,比如
app.abc123.js变成app.def456.js - 不要全局设置无缓存头:之前的问题根源就是把
no-cache等头全局配置了,导致所有资源都被强制不缓存,一定要做路径精确匹配 - 验证配置效果:用浏览器开发者工具的Network面板,查看每个资源的Response Headers,确认
index.html和JS/CSS的Cache-Control字段符合预期;发布新版本后,观察index.html的请求状态是200(更新)或304(未变),JS/CSS则直接从缓存读取
内容的提问来源于stack exchange,提问作者Ominus
相关产品推荐
相关产品推荐

