proxy_set_header 是 Nginx 负载均衡中必须正确配置的关键指令,用于透传 Host、X-Real-IP、X-Forwarded-For 三个基础头,以及 HTTPS 场景下的 X-Forwarded-Proto 和 X-Forwarded-Host,WebSocket 还需 Upgrade 和 Connection 头;变量拼写、引号使用及不覆盖不补全等细节直接影响后端识别客户端身份、协议与路径的准确性。

在 Nginx 负载均衡场景中,proxy_set_header 不是可选项,而是决定后端服务能否正确识别客户端身份、协议、路径的关键配置。它不改变 Nginx 自身行为,只控制“发给后端的请求头长什么样”。配错会导致 IP 取不到、HTTPS 判断失败、Host 解析异常、WebSocket 断连等典型问题。
必须透传的三个基础请求头
无论后端是 Java、Python 还是 Node.js,只要走 HTTP 协议,以下三项就构成最小安全配置:
-
Host 头:用
proxy_set_header Host $http_host;(推荐)或$host。前者保留原始请求中的端口(如example.com:8080),后者会丢弃非标准端口;若后端依赖 Host 做虚拟主机路由或生成绝对 URL,缺此项会直接 404 或跳转错误。 -
X-Real-IP 头:用
proxy_set_header X-Real-IP $remote_addr;。它把最外层客户端真实 IP 写入该字段,后端可通过request.getHeader("X-Real-IP")直接获取,无需解析复杂链路。 -
X-Forwarded-For 头:用
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;。该变量自动判断上游是否已有该头——若有,追加当前$remote_addr;若无,直接设为$remote_addr。比硬写$remote_addr更健壮,适配 CDN 或多级代理环境。
HTTPS 和协议感知场景要补的头
当 Nginx 终止 SSL(即 HTTPS 入口,HTTP 转发给后端),后端若自行判断协议或生成重定向链接,必须告知原始协议类型:
-
X-Forwarded-Proto:设为
$scheme。后端据此知道用户实际访问的是https://还是http://,避免强制跳 http 或混合内容警告。 -
X-Forwarded-Host:设为
$host。尤其在泛域名解析、多租户或 Host 改写(如rewrite后)时,确保后端拿到的是用户最初访问的域名,而非 upstream 中写的固定地址。
WebSocket 和长连接支持要点
启用 WebSocket 需同时设置两个头,且大小写和值必须严格匹配:
-
Upgrade:用
proxy_set_header Upgrade $http_upgrade;。Nginx 会把客户端请求头里的Upgrade: websocket原样转发。 -
Connection:用
proxy_set_header Connection "upgrade";。注意值必须是带双引号的字符串"upgrade",不能写成变量或漏掉引号,否则连接降级为普通 HTTP。
容易踩坑的细节提醒
这些不是“高级技巧”,而是上线前必须核对的实操要点:
- 变量拼写不能错:
$remote_addr不是$realip,$proxy_add_x_forwarded_for不是$x_forwarded_for。 - 不要覆盖关键头却不补全:比如只写
proxy_set_header Host backend.example.com;却不传X-Real-IP,后端将失去客户端 IP。 - 缓存相关头(如
Cache-Control)虽可用proxy_set_header设置,但属于业务逻辑控制,不属于“必配项”,按需添加即可。 -
proxy_set_header只影响发给后端的请求头,和浏览器看到的响应头无关——跨域头(Access-Control-Allow-Origin)必须用add_header,两者作用对象完全不同。


















