nginx通过add_header指令配置自定义响应头,支持http/server/location块,需加always参数才对所有状态码生效,配合map可实现多域名差异化设置,但会被后端header()覆盖、不继承父级同名头、proxy_set_header无效。

在 Nginx 中通过 nginx.conf 配置自定义响应头,核心是使用 add_header 指令,它原生支持、无需额外模块,且可灵活作用于 http、server 或 location 块。
基本写法:用 add_header 添加静态头
在对应作用域内直接写:
add_header X-App-Version "v2.4.1";add_header X-Frame-Options "DENY";add_header Cache-Control "no-cache, no-store";
注意:值中可含变量(如 $request_id),但若变量为空,该响应头不会发出;名称和值严格区分大小写。
控制生效范围:always 参数很关键
默认情况下,add_header 只对部分状态码生效(如 200、301、304 等),不覆盖 404、500、302 等常见响应。需要统一输出时,必须加 always:
-
add_header X-Trace-ID $request_id always;—— 所有状态码都会带这个头 - 不加
always时,return 404或error_page 404的响应里不会包含该头
多域名/多路径差异化配置:用 map + 变量
当需按域名或路径动态设值(如 api.example.com → X-Service: api),推荐在 http 块顶部用 map 预定义:
map $host $service_name {
api.example.com "api";
admin.example.com "admin";
default "web";
}
然后在 server 或 location 中引用:
add_header X-Service $service_name;-
map必须放在http块最外层,不能嵌套在server内
避免常见失效场景
这些情况会导致自定义头“看似配置了却没出现”:
- PHP 等后端脚本自己调用了
header(),会覆盖 Nginx 的响应头(Nginx 头优先级低于后端输出) - 用了
proxy_set_header——它只改发给后端的请求头,不影响返回给客户端的响应头 - 同名头在子作用域(如
location)中未重复声明,父级(server)的头会被完全屏蔽,不继承 - CORS 场景下,前端带了
X-User-ID,但没在Access-Control-Allow-Headers中显式列出,浏览器直接拦截主请求











