Nginx中add_header不支持继承,仅在命中的location内生效且同名覆盖;internal重定向后原location头失效;默认仅作用于2xx/3xx响应,需always参数才覆盖4xx/5xx。

Nginx 本身不支持 location 嵌套,所谓“多级 location 嵌套”在语法上是非法的,配置会直接报错。因此不存在“嵌套下变量生效范围”这一场景——add_header 的作用域问题,本质是配置层级继承与覆盖规则,而非嵌套作用域。
add_header 不继承,只覆盖
只要某个 location 块中出现任意一条 add_header 指令,该 location 就完全放弃继承上级(server 或 http)定义的同名响应头,只保留自己内部声明的那些。
- http 块设了 add_header X-Content-Type-Options "nosniff";
- server 块没写 add_header;
- 但 location /api/ 里写了 add_header Cache-Control "no-store";
- 那么访问 /api/ 时,X-Content-Type-Options 就不会出现在响应头中。
internal 重定向时,add_header 不传递
使用 try_files、rewrite last、error_page 或 named location 触发 internal 跳转后,原 location 的 add_header 完全失效,只有目标 location 中显式配置的 add_header 才生效。
- location / { try_files $uri @backend; }
- location @backend { internal; add_header X-Source "upstream"; }
- 最终响应只含 X-Source: upstream,主 location 中的 add_header 一条都不带。
同名 header 默认覆盖,不是叠加
同一 location 内多次使用 add_header 设置相同名称,后写的会覆盖前写的;跨 location 之间不叠加,只看最终命中的那个 location 有没有定义。
- location /admin/ { add_header X-Robots-Tag "noindex"; add_header X-Robots-Tag "noarchive"; }
- 实际生效的是 "noarchive";
- 想同时生效需用不同 header 名,或借助 proxy_hide_header + proxy_pass_header 等组合控制上游头。
4xx/5xx 响应默认不加头,always 是关键开关
add_header 默认只对 2xx/3xx 响应生效(如 200、302、304),遇到 404、500 等错误响应时,这些头根本不会发出——除非加上 always 参数。
- add_header Strict-Transport-Security "max-age=31536000" always; → 错误页也带 HSTS
- add_header X-Frame-Options "DENY" always; → 防止点击劫持,覆盖所有状态码
- 安全类响应头建议统一加 always,避免被绕过











