在nginx中透传自定义http请求头需启用underscores_in_headers on并显式配置proxy_set_header,否则含下划线的头会被静默丢弃,且必须重写所有需传递的头(包括host等默认头)以避免丢失。

在 Nginx 中向后端(如 FastAPI、Django、Node.js 等)透传自定义 HTTP 请求头,关键在于两件事:一是确保客户端发来的头不被 Nginx 过滤掉,二是显式用 proxy_set_header 将其转发给上游服务。
确认请求头未被 Nginx 自动忽略
Nginx 默认会忽略下划线(_)开头或含下划线的请求头(例如 X-User-ID 允许,但 X_User_ID 或 my_header 可能被静默丢弃)。这是出于安全考虑,防止与内部变量名冲突。
- 若自定义头含下划线,需在
http或server块中添加:
underscores_in_headers on; - 该指令只影响读取客户端请求头,不影响 Nginx 自己设置的头
用 proxy_set_header 显式转发
Nginx 不会自动把所有收到的请求头都传给后端。必须为每个想透传的头单独配置 proxy_set_header。
- 例如透传
X-Request-ID和X-Forwarded-User:
proxy_set_header X-Request-ID $http_x_request_id;
proxy_set_header X-Forwarded-User $http_x_forwarded_user; -
$http_*是 Nginx 内置变量,自动提取对应小写连字符格式的请求头(如X-Request-ID→$http_x_request_id) - 若头名含下划线且已启用
underscores_in_headers,变量名为$http_my_header(对应My-Header或my_header)
避免覆盖默认行为或丢失关键头
注意 proxy_set_header 是覆盖式操作。Nginx 有默认头(如 Host、Connection),一旦你在 location 中写了任意 proxy_set_header,就必须**显式重写所有需要的头**,否则默认值会丢失。
- 推荐在
location中保留基础头:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; - 再追加你的自定义头,顺序无关
验证是否生效
最直接的方式是在后端打印所有接收到的请求头。例如在 Python Flask 中:
print(dict(request.headers))
同时可用 curl -H "X-Custom-Test: hello" http://your-nginx-domain/ 测试端到端链路,观察后端日志是否出现该字段。











