核心是按资源类型精准设置 cache-control:哈希静态资源用 public, max-age=31536000, immutable;普通静态资源用 public, max-age=2592000;html 文件必须 no-cache 或 no-cache, must-revalidate,并用 always 强制覆盖,上线后需验证响应头。

核心是按资源类型精准设置 Cache-Control 指令,而不是统一加个 expires 或笼统写 public。Nginx 本身不自动生成 Cache-Control,必须用 add_header 显式声明,才能控制浏览器和 CDN 的缓存行为。
匹配带哈希的静态资源(JS/CSS/图片)
这类文件名含内容哈希(如 app.8a3b2c.js),说明内容不变则路径不变,适合启用“永久+不可变”缓存:
- 用正则匹配常见哈希格式:
location ~* "\.[a-f0-9]{8,}\.(js|css|png|jpg|jpeg|gif|svg|webp|woff2?)$" - 设置强缓存头:
add_header Cache-Control "public, max-age=31536000, immutable"; - 可附加
expires 1y;兼容 HTTP/1.0 客户端 - 建议关闭日志:
access_log off;减少磁盘开销
匹配普通静态资源(无哈希但变动少)
如 logo.png、字体文件、未哈希的 CSS/JS,适合设中长期缓存,允许后续验证:
- 按后缀匹配:
location ~* \.(png|jpg|jpeg|gif|svg|webp|ico|woff|woff2|ttf|eot)$ - 设 30 天缓存:
add_header Cache-Control "public, max-age=2592000"; - 不加
immutable,保留 ETag 或 Last-Modified 验证能力
严格禁用 HTML 文件的强缓存
index.html 是资源入口,一旦被强缓存,新 JS/CSS 就无法加载,极易导致白屏或功能异常:
- 对所有 HTML 文件:
location ~* \.html$ { add_header Cache-Control "no-cache, must-revalidate"; } - 根路径也要覆盖:
location = / { try_files /index.html =404; add_header Cache-Control "no-cache"; } - 避免用
max-age=0,它仍可能触发条件请求;no-cache更可靠
注意覆盖逻辑与生效验证
Nginx 的 add_header 默认不覆盖上游已设的同名头(如 PHP 或代理返回的 Cache-Control),需加 always 强制覆盖:
- 例如:
add_header Cache-Control "public, max-age=86400" always; - 上线后立刻检查 Network 面板:HTML 响应头应为
no-cache,哈希 JS 应含immutable和max-age=31536000 - 手动改一行 HTML 并部署,清缓存重进——若仍是旧版,说明 location 优先级低或配置被其他块覆盖











