必须为 add_header 显式添加 always 参数,才能使 Cache-Control 等头在 4xx/5xx 响应中生效;默认仅对 2xx/3xx 状态码生效,错误响应会被忽略。

要让 Nginx 在 4xx 或 5xx 响应中也输出缓存控制头(如 Cache-Control、Expires),必须为 add_header 显式加上 always 参数。默认情况下,这些头只出现在 2xx/3xx 成功响应里,错误响应会直接忽略——这会导致前端在收到 404 或 500 时拿不到你设定的缓存策略,甚至被浏览器或 CDN 按默认规则缓存错误页。
为什么默认不生效
Nginx 官方文档明确说明:add_header 仅对状态码为 200、201、204、206、301、302、303、304、307 的响应生效。400、403、404、500、502 等错误响应完全跳过该指令。即使你在 server 块顶层配置了 add_header Cache-Control "no-store",它也不会出现在 500 页面的响应头中。
always 参数的实际作用
always 不是“开关”,而是强制覆盖默认行为的标记。它让指定的响应头在所有 HTTP 状态码下都输出,包括 404、500、502、503 等。注意三点:
-
always必须写在每行add_header的末尾,不能省略,也不能加引号或换行 - 它从 Nginx 1.7.5 开始支持,低版本无效
- 多个
add_header指令之间不继承always,每一行都要单独加
常见缓存头配置示例
以下写法可确保 Cache-Control 和 Pragma 在任意响应中都生效:
add_header Cache-Control "no-cache, no-store, must-revalidate" always;add_header Pragma "no-cache" always;add_header Expires "0" always;
如果使用 expires 指令(如 expires -1),它本身就会自动设置 Expires 和 Cache-Control,并隐式覆盖后端头,无需额外加 always;但若坚持用 add_header 控制缓存头,always 就不可少。
配合 error_page 使用时的注意事项
当你配置了自定义错误页,例如:
error_page 404 /404.html;error_page 500 /50x.html;
这些错误页由独立的 location 块处理(如 location = /404.html)。如果该块里没写带 always 的 add_header,那么返回的 404 页面依然不会携带你期望的缓存头。正确做法是:
- 在
location = /404.html内显式添加带always的缓存头 - 或把带
always的add_header放在server块顶层,确保覆盖所有子 location(包括 error_page 路由)

















