Nginx配置静态资源强缓存需三者协同:精准匹配资源路径(如location ^~ /static/或正则匹配后缀)、按是否含哈希分档设置长时效缓存头(带哈希设max-age=31536000且immutable,无哈希设2592000)、必须用add_header统一写全Cache-Control并验证响应头与浏览器缓存行为。

在 Nginx 中配置静态资源的强缓存,核心不是“设一个时间就完事”,而是让浏览器真正跳过请求、直接复用本地副本。这需要三件事同时到位:精准匹配资源、设置足够长且语义明确的缓存头、确保资源 URL 本身能反映内容变化。
精准匹配你要缓存的文件
别用 location / 或 location ~ \.html$ 这类宽泛规则,否则 HTML、API 接口也会被误缓存,引发线上事故。推荐两种安全写法:
- 用不区分大小写的正则匹配常见静态后缀:location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2|ttf|eot|webp)$
- 如果静态资源统一放在 /static/ 或 /assets/ 目录下,优先用前缀匹配:location ^~ /static/(性能更高,无正则开销)
按资源是否带哈希,分档设有效期
缓存时长不能拍脑袋定。关键看文件名里有没有内容哈希(如 app.a1b2c3.js)或版本号。哈希变了,URL 就变,浏览器自然加载新资源;哈希不变,说明内容没动,可放心缓存很久。
- 带哈希的 JS/CSS/字体/WebP:设 expires 1y; 或 expires max;,再加 add_header Cache-Control "public, immutable, max-age=31536000";
- 图片、图标等稳定但无哈希的资源(如 logo.png):设 expires 30d;,配 add_header Cache-Control "public, max-age=2592000";
- HTML、PHP、JSON 等动态内容:必须禁用强缓存,用 expires epoch; 和 add_header Cache-Control "no-cache, must-revalidate, max-age=0";
必须补全 Cache-Control,且只写一次
expires 指令只生成基础响应头,现代浏览器更依赖 Cache-Control。它语义更清晰,不受客户端系统时间影响(Expires 依赖 GMT 时间,用户改系统时间就会出问题)。注意两点:
- immutable 是关键——告诉浏览器“这个资源整个生命周期内都不会变”,F5 刷新也不发 If-None-Match 请求,彻底跳过协商缓存
- add_header 在同一作用域内多次声明会覆盖,务必把所有 Cache-Control 指令合并成一条,比如 "public, immutable, max-age=31536000"
改完一定要验证,别信“写了就生效”
配置上线前必须确认响应头真实发出且格式正确:
- 先运行 nginx -t 检查语法
- 再执行 nginx -s reload 重载
- 用 curl -I https://your-site/app.a1b2c3.js 查看响应头,确认同时存在 Cache-Control 和 Expires
- 打开 Chrome DevTools → Network → 刷新页面,找对应资源,状态码应为 200 (from memory cache) 或 200 (from disk cache),而不是 304 或 200(从服务器)











