静态资源缓存自动失效的核心是控制响应头、资源指纹和代理缓存策略;通过文件哈希(如app.a1b2c3.js)实现自然失效,nginx对带哈希资源设强缓存,html用no-cache协商缓存,并配合proxy_cache实现动态页缓存刷新。

静态资源缓存的自动失效,关键不在“让缓存主动删除”,而在于让浏览器和 Nginx 都按预期不复用旧内容——核心是控制响应头 + 合理利用资源指纹 + 配置代理缓存策略。
用文件哈希指纹实现“自然失效”
这是最可靠、最主流的做法。把 JS/CSS/图片等资源名中加入内容哈希(如 app.a1b2c3.js),每次内容变更,文件名就变,浏览器视为全新资源,自动绕过旧缓存。
实际配置示例:
- 构建工具(Webpack/Vite)开启
filename: "[name].[contenthash:8].js" - Nginx 中对带哈希的资源启用强缓存:
location ~* \.[a-f0-9]{8,}\.(js|css|png|jpg|gif|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
对无哈希的资源(如 HTML)做验证式缓存
HTML 通常不加哈希,但又不能长期缓存。应避免用 no-store 这类彻底禁用缓存的指令,改用 no-cache,让浏览器每次请求时携带 If-None-Match 或 If-Modified-Since,由 Nginx 返回 304 协商缓存。
配置要点:
- 确保 HTML 响应带
ETag或Last-Modified(Nginx 默认开启) - 明确设置:
location ~* \.html$ {
add_header Cache-Control "no-cache, must-revalidate";
} - 不要在高优先级 location(如
^~/)里用add_header覆盖所有子路径,否则会误伤静态资源
配合 proxy_cache 实现后端响应的自动刷新
当 Nginx 作为反向代理缓存动态生成的静态页(如 PHP 渲染的 HTML),需靠 proxy_cache_valid 和 proxy_cache_use_stale 控制失效逻辑:
-
proxy_cache_valid 200 10m;:成功响应缓存 10 分钟 -
proxy_cache_use_stale error timeout updating;:后台更新时,仍可返回旧缓存,避免雪崩 - 配合
proxy_cache_lock on;防止缓存穿透时多个请求同时回源 - 通过
proxy_cache_bypass $arg_nocache;支持手动刷新(如加?nocache=1)
务必避开的常见陷阱
很多“缓存不更新”问题其实不是失效没配好,而是被更高优先级规则覆盖或协议干扰:
- 检查 location 优先级:正则匹配(
~ \.js$)会被^~ /static/这类前缀匹配拦截,导致 expires 不生效 → 把缓存指令写进对应 location 内,或改用if判断(谨慎) - HTTPS 下混用 HTTP 资源会触发混合内容拦截,浏览器直接拒载 → 全站静态资源链接必须为 HTTPS 或协议相对
- 浏览器本地缓存优先于 Nginx 缓存:若用户始终不发新请求,Nginx 就没机会更新 → 必须靠响应头驱动浏览器行为,不能依赖 Nginx 单方面清理磁盘文件











