Nginx反向代理通过proxy_set_header等指令控制请求头转发,需显式配置Host、X-Real-IP等头以保留客户端信息;默认会清除Connection等头,且Host默认设为$proxy_host而非原始值,必须用$http_host覆盖;调试可借助后端日志、httpbin回显或Nginx debug日志精准比对。

要测试 Nginx 作为反向代理时请求头的转发与变化,核心是对比客户端直连后端服务(绕过 Nginx)和经由 Nginx 代理访问时,后端收到的请求头差异。关键在于控制变量、显式观察原始头和被修改/添加的头。
用 curl 模拟不同路径并捕获完整请求头
在后端服务(如一个简单的 Python Flask 或 Node.js 服务)中打印所有接收到的 HTTP 请求头,这是最直接的观测方式。
- 先不走 Nginx:用
curl -v http://localhost:8000/test(假设后端监听 8000),记录响应头及服务端日志中的请求头 - 再走 Nginx:确保 Nginx 配置中开启了必要的头透传(如
proxy_set_header Host $host;、proxy_set_header X-Real-IP $remote_addr;等),然后执行curl -H "X-Custom: test" -v http://your-domain/test - 对比两次后端日志中打印出的
request.headers字典(或等效结构),重点关注Host、X-Forwarded-For、X-Real-IP、User-Agent、自定义头是否保留或被覆盖
检查 Nginx 默认行为与常见覆盖点
Nginx 在代理过程中会自动重写部分请求头,且默认不转发所有客户端头:
-
Host头默认被设为proxy_set_header Host $proxy_host;(即 upstream 的 host),若需保留原始 Host,应显式写成proxy_set_header Host $http_host;或$host:$server_port -
Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization、TE、Trailers、Upgrade、Content-Length这些头默认被清除,除非你用proxy_pass_request_headers on;并手动proxy_set_header -
Accept-Encoding若未显式设置,Nginx 可能因启用 gzip 而改写,建议固定为proxy_set_header Accept-Encoding "";来透传原始值
用 echo server 快速验证(无需改后端代码)
部署一个现成的 echo 服务(例如 httpbin.org/headers 或本地运行 python3 -m http.server --bind 127.0.0.1:8000 配合简单 echo 脚本),然后分别请求:
- 直连:
curl http://localhost:8000/headers - 代理:
curl -H "X-Test: abc" http://your-nginx-domain/headers - 观察 JSON 响应中各字段,确认
X-Test是否出现、Host值是否为 Nginx 域名、是否有X-Forwarded-For等新增头
开启 Nginx debug 日志精准追踪头处理过程
在 nginx.conf 的 http 或 location 块中临时加入:
error_log /var/log/nginx/debug.log debug;
重启 Nginx 后发起一次请求,查看 debug.log 中类似以下日志行:
[debug] ... http proxy header: "Host: example.com" [debug] ... http proxy header: "X-Real-IP: 192.168.1.100" [debug] ... http proxy header: "X-Forwarded-For: 192.168.1.100"
这能明确看到 Nginx 实际发往后端的是哪些头、顺序如何、是否被重写。


















