nginx可通过map预定义变量实现动态响应头重写,结合add_header、proxy_hide_header及proxy_redirect等指令,按域名、路径、参数等上下文实时控制头字段的增删改与重定向修正。

动态重写后端响应头,不是简单地加几个 add_header,而是根据请求上下文(如域名、路径、参数、客户端特征)实时决定是否改写、改写成什么。Nginx 本身不支持在响应阶段做条件判断,所以必须靠“预判+变量驱动”来实现真正的动态性。
用 map 预定义响应头值,实现按需切换
map 指令在 server 或 http 块中定义,它能在请求解析阶段就根据变量生成新变量,后续可直接用于 add_header 或 proxy_hide_header:
- 例如,让不同子域名返回不同的
X-Backend-Version:
default "v1.2";
staging.example.com "v1.3-staging";
dev.example.com "v1.4-dev";
}
然后在 location 中使用:
add_header X-Backend-Version $backend_version always;- 再比如,根据请求是否带
?debug=1,动态开启详细错误头:
"1" "on";
default "off";
}
add_header X-Debug-Mode $show_real_error always;
proxy_intercept_errors $show_real_error;
结合 proxy_hide_header + add_header 实现头覆盖逻辑
后端常自带 Server、X-Powered-By、Cache-Control 等头,要动态控制是否隐藏、是否替换,不能只靠静态配置:
- 先统一屏蔽原始头(避免透传干扰):
proxy_hide_header X-Powered-By;
proxy_hide_header Cache-Control;
- 再按规则注入新头:
~^/static/ "public, max-age=3600";
~^/api/ "no-store, must-revalidate";
default "no-cache";
}
add_header Cache-Control $cache_policy always;
利用 $sent_http_* 变量做响应后判断(有限但实用)
Nginx 提供了 $sent_http_* 系列变量,表示已发送给客户端的响应头值,可用于日志记录或简单分流(注意:不能用于修改响应头本身,仅作只读参考):
- 记录后端实际返回的状态与内容类型:
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'"$sent_http_content_type" "$sent_http_x_backend_id"';
- 配合 if(慎用)做简单响应拦截(如拦截特定 Content-Type 的错误响应):
add_header X-Handled-As-JSON "true" always;
}
⚠️ 注意:if 在 location 中对响应头操作有局限,推荐优先用 map + add_header 组合。
处理重定向响应头的动态修正
后端 302 跳转的 Location 头往往含内网地址或错误协议,需动态适配公网访问场景:
- 用正则匹配并替换协议和主机:
- 更精细控制:只对特定路径下的跳转生效(如仅 /auth/ 下的重定向走 HTTPS):
proxy_pass http://auth-backend;
proxy_redirect ~^http://.*(/.*)?$ https://$host$1;
}
- 配合
X-Forwarded-Proto保证后端生成跳转时也用正确协议:
proxy_set_header X-Forwarded-Host $host;











