Nginx中add_header不继承只覆盖,location内声明即重置全部响应头;internal重定向后原location头失效;OPTIONS需加always;同名头后定义覆盖前定义。

Nginx 语法根本不允许“多级 location 嵌套”——配置会直接报错,所谓“嵌套下的变量作用域”是个伪命题。真正要搞清的,是 add_header 在不同配置层级间的覆盖规则、执行时机和常见失效路径。
add_header 不继承,只覆盖:location 一写就丢父级头
只要某个 location 块里出现任意一条 add_header,它就自动放弃继承 server 或 http 块中所有同名响应头。这不是值被替换,而是整个头集合被重置为“仅本 location 内声明的那些”。
- 你在
server块写了add_header X-Content-Type-Options "nosniff";,但location /api/里只写了add_header Cache-Control "no-store";→ 访问/api/时,X-Content-Type-Options就彻底消失 - 想保留父级安全头?必须在每个用到
add_header的location里手动重复写一遍,或用include引入公共头配置文件 -
http块的add_header权重最弱,一旦任一server或location定义了同名头,它就立即失效
internal 重定向后,原 location 的 add_header 全部作废
用 try_files、rewrite ... last、error_page 或 named location 触发 internal 跳转时,Nginx 会完全丢弃原 location 的 add_header,只看目标 location 是否显式声明。
-
location / { try_files $uri @backend; }+location @backend { internal; add_header X-Source "upstream"; }→ 最终响应只有X-Source: upstream,主location里的任何add_header都不生效 -
rewrite ^/old/(.*)$ /new/$1 last;会跳进location /new/,此时只有该块内的add_header生效 -
break不触发 internal 重定向,仍在同一location,原有add_header继续有效
OPTIONS 预检请求必须加 always,否则 CORS 头根本不出现在响应里
add_header 默认只对 2xx/3xx 响应生效。而 OPTIONS 预检成功时返回的是 204(属于 2xx),看似够用——但很多配置漏掉关键点,导致预检失败。
- 把
add_header Access-Control-Allow-Origin "$http_origin" always;写在if ($request_method = 'OPTIONS') { return 204; }外面,且没加always→ 实际 OPTIONS 响应里没有 CORS 头 - 必须把所有 CORS 相关
add_header放在同一个location块内,并全部带上always参数,例如:add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; - 若用
proxy_pass,CORS 头必须写在proxy_pass所在的location块里,写在server或上层location无效
同名 header 在同一 location 内后定义覆盖前定义,不是叠加
同一个 location 里多次使用 add_header 设置相同名称,Nginx 按配置顺序取最后一个值,前面的全被覆盖。
-
add_header X-Robots-Tag "noindex";和add_header X-Robots-Tag "noarchive";写在一起 → 实际只发X-Robots-Tag: noarchive - 想同时生效两个值?不能靠重复
add_header,得换思路:用不同 header 名,或借助proxy_hide_header+proxy_pass_header控制上游头合并 - 注意变量作用域:
$http_origin这类变量在if块外可用,但在某些上下文(如map或非标准块)可能未定义,需验证是否为空
最容易被忽略的是:add_header 的生效完全取决于最终命中的那个 location,而不是你“以为”它该从哪继承。写配置前先确认请求到底落在哪个块里,再检查那个块是否显式包含了所有需要的头——别指望 Nginx 自动帮你拼起来。


















