关键在于Nginx通过proxy_set_header传递X-Forwarded-Port和X-Forwarded-Proto头部,后端应用据此构建重定向URL,避免暴露内部端口;多级代理需逐层透传并配置信任,最终确保Location头使用用户访问的端口与协议。

核心在于让后端应用知道用户最初访问的是哪个端口,而不是它自己监听的内部端口。当请求经过 Nginx 代理(尤其是多级代理)后,若后端生成重定向 URL 时直接调用 request.getServerPort() 或类似逻辑,就会把真实服务端口(如 8080、9080)写进 Location 头,导致浏览器跳转到错误端口(如 http://domain:9080/login),绕过负载均衡器。
关键配置:用 proxy_set_header 传递原始端口
在 Nginx 的 location 或 server 块中,显式设置两个关键头部:
-
proxy_set_header X-Forwarded-Port $server_port;—— 透传 Nginx 接收请求时使用的端口(即用户访问的端口,如 80 或 443) -
proxy_set_header X-Forwarded-Proto $scheme;—— 透传原始协议(http或https),避免 HTTPS 降级
示例配置:
location / {
proxy_pass http://backend;
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;
proxy_set_header X-Forwarded-Port $server_port;
}
后端必须读取并信任这些头部
仅透传不够,后端应用需主动使用 X-Forwarded-Port 和 X-Forwarded-Proto 构建重定向 URL,而非依赖原始请求端口。不同框架处理方式不同:
-
Spring Boot:启用
server.forward-headers-strategy=framework,并确保ForwardedHeaderFilter生效;或配置TomcatServletWebServerFactory启用远程端口解析 -
WebSphere(WAS):必须设置 JVM 自定义属性:
trusthostheaderport=true和com.ibm.ws.webcontainer.extractHostHeaderPort=true,否则忽略X-Forwarded-Port -
Java Servlet 容器(如 Tomcat):在
server.xml的Connector中添加remotePortHeader="X-Forwarded-Port"和protocolHeader="X-Forwarded-Proto"
多级代理场景下的注意事项
若存在 Nginx → F5 → WAS 这类多层代理,需确保每一级都正确传递并覆盖 X-Forwarded-* 头部:
- F5 需开启“插入 X-Forwarded-* 头”功能,并配置为信任上一级(Nginx)IP
- Nginx 的
proxy_set_header应放在最外层,且避免被内层覆盖(例如不要在子 location 中重复设置) - 所有中间层必须禁用自动重写
Host或Location头的行为(如 Nginx 默认不改写 Location,但某些模块或配置可能干预)
验证是否生效
用 curl -I 检查响应头是否正常:
- 发起一个会触发重定向的请求(如未登录访问受保护路径)
- 观察返回的
Location头是否为https://domain.com/login(无端口),而非https://domain.com:8080/login - 同时检查后端日志或调试输出,确认
request.getRemotePort()或等效方法返回的是X-Forwarded-Port值,而非容器监听端口











