Nginx中设置Cache-Control需用add_header配合always参数显式声明max-age,并按资源类型分组配置:哈希静态资源设31536000秒+immutable,普通静态资源设2592000秒,HTML禁用强缓存;须加ignore_headers防后端覆盖,禁用expires混用。

在 Nginx 中设置 Cache-Control 相对缓存控制头,核心是用 add_header 显式声明 max-age 值,并确保它真正生效——Nginx 不会自动根据文件类型或时间生成该头,也不会继承或覆盖上游(如 PHP、代理)已设的同名响应头,必须主动、精准、强制地写入。
按资源类型分组设置 max-age
不同静态资源应匹配不同缓存时长,避免“一刀切”:
-
带哈希的 JS/CSS/图片(如
app.a1b2c3.js):内容不变则路径不变,适合长期强缓存location ~* "\.[a-f0-9]{8,}\.(js|css|png|jpg|gif|svg|webp|woff2?)$" {<br> add_header Cache-Control "public, max-age=31536000, immutable" always;<br> access_log off;<br> } -
普通静态资源(如
logo.png、字体、未哈希 CSS):变动频率低但非绝对不变,保留验证能力location ~* \.(png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$ {<br> add_header Cache-Control "public, max-age=2592000" always;<br> } -
HTML 文件(含根路径
/):必须禁用强缓存,防止白屏或功能错乱location ~* \.(html|htm)$ {<br> add_header Cache-Control "no-cache, must-revalidate" always;<br> }<br> location = / {<br> try_files /index.html =404;<br> add_header Cache-Control "no-cache" always;<br> }
确保 max-age 生效的关键操作
add_header 默认不覆盖后端返回的 Cache-Control,也不作用于 304/206 等非 200 响应。要可靠生效,必须:
- 加
always参数:强制写入所有响应状态码,包括 304、404、50x - 配合忽略上游头:若后端(如 PHP-FPM)自己输出了
Cache-Control,需加fastcgi_ignore_headers Cache-Control;;若用反向代理,加proxy_ignore_headers Cache-Control; - 避免与
expires指令混用:两者都会设Cache-Control,易冲突。推荐统一用add_header控制,更清晰可控
验证是否配置成功
上线后立即检查浏览器开发者工具的 Network 面板:
- 打开一个哈希 JS 文件,响应头中应出现:
Cache-Control: public, max-age=31536000, immutable - 访问
/或/about.html,响应头中应为:Cache-Control: no-cache, must-revalidate(不能是max-age=0或空值) - 手动修改 HTML 内容并重新部署,清空浏览器缓存后重进——若仍加载旧版,说明 location 匹配失败或被其他配置块覆盖
不建议的写法
这些看似简洁的做法实际不可靠:
-
expires 1h;:它会自动设Cache-Control: max-age=3600,但无法添加immutable或public等指令,灵活性差 -
add_header Cache-Control "max-age=3600";(无always):对 304 响应无效,CDN 可能忽略,PHP 返回的头也可能覆盖它 -
add_header Cache-Control "no-cache";(无always+ 无ignore_headers):后端若返回public, max-age=86400,最终响应头可能仍是后者


















