add_header 指令不继承,而是覆盖式叠加:子作用域定义时完全忽略父作用域同名指令,仅生效当前块中的头;需手动重复声明父级头或用 include 统一管理。

add_header 指令的继承规则本质
add_header 不会自动继承,而是“覆盖式叠加”:在子作用域(如 location)中定义 add_header 时,会完全忽略父作用域(如 server 或 http)中同名的 add_header,只生效当前块中定义的头。这不是覆盖值,而是覆盖整个指令集——父级定义的响应头在该 location 内默认不出现,除非显式重新声明。
三种典型配置层级的行为对比
1. http 块中设置(全局默认,但最弱)
定义在 http { } 中的 add_header 对所有 server 和 location 生效——仅当子块未定义任何 add_header 时。一旦某个 server 或 location 内写了 add_header,http 级的配置立即失效。
2. server 块中设置(对本虚拟主机有效,仍可被 location 覆盖)
server { } 中的 add_header 对该 server 下所有未定义 add_header 的 location 生效;但只要某个 location 内有 add_header 指令,该 location 就只认自己的,server 级的头全部丢失。
3. location 块中设置(最优先,完全隔离)
location /api { add_header X-Backend "nginx"; } → 此 location 返回的响应中,仅包含这一行头,即使 server 里写了 X-Frame-Options、X-Content-Type-Options,也全都不见。
如何让父级 header 在 location 中继续生效?
必须手动“继承”——在子块中重复写父级需要的头。常见做法:
- 把通用安全头提取成变量或注释模板,避免遗漏
- 在 location 中显式补全:比如 server 里设了 X-Frame-Options SAMEORIGIN,location /admin 也要再写一遍
- 用 include 拆分公共头配置,例如:
include security-headers.conf;
在多个 server 或 location 中引用同一文件,保证一致性
实战验证小技巧
快速确认实际返回哪些 header:
- 用 curl -I 请求目标 URL,观察响应头列表
- 在 location 中临时加一行:
add_header X-Debug-Location "yes";
若看到该头,说明 location 级生效;若没看到其他预期头,就证实它们已被屏蔽 - 注释掉 location 内的 add_header,再测试——如果其他头突然出现,即验证了“无定义才继承”的行为

















