必须显式设置x-forwarded-port,因后端调用getserverport()获取的是nginx内部通信端口(如8080),而非用户访问端口(如443);若缺失该头,将生成错误绝对url,导致资源加载失败或跳转异常。

要让后端应用生成正确的绝对 URL(比如 https://example.com/assets/style.css 而不是 http://localhost:8080/assets/style.css),关键在于把用户实际访问的端口准确告诉后端——Nginx 默认不传 X-Forwarded-Port,必须手动配置。
为什么必须显式设置 X-Forwarded-Port
后端应用(如 Spring Boot、Django、Node.js)在拼接重定向地址或静态资源路径时,常调用类似 request.getServerPort() 的方法。它读到的是 Nginx 与它通信的本地端口(如 8080),而非用户浏览器访问的端口(如 443 或 80)。缺失 X-Forwarded-Port,就会把内部端口暴露出去,导致链接失效、跳转错误甚至安全策略拦截。
在 location 块中正确写法
该头必须放在 proxy_pass 所在的 location 块内,且推荐按协议标准值设置,而非监听端口:
- HTTPS 请求 → 设为
443(即使 Nginx 监听 8443,也应设 443) - HTTP 请求 → 设为
80(即使监听 8080,也不写 8080) - 用
$server_port变量自动适配:proxy_set_header X-Forwarded-Port $server_port; - 若需严格遵循 RFC 7239(例如对接某些云平台),可配合
map做标准化映射
必须配套透传的其他关键头
单传 X-Forwarded-Port 不够,后端需综合判断才能构建正确 URL:
-
proxy_set_header X-Forwarded-Proto $scheme;—— 告知真实协议(http/https),防止 HTTPS 降级或死循环 -
proxy_set_header Host $host;—— 传域名,不带端口(避免出现example.com:443) -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;—— 保留原始客户端 IP 链路 - 可选但推荐:
proxy_set_header X-Forwarded-Host $host;,辅助后端识别请求来源
后端必须启用信任并解析这些头
Nginx 传了不代表后端会用。常见框架需显式开启转发头支持:
- Spring Boot:配置
server.forward-headers-strategy=framework - Django:设置
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')并启用USE_X_FORWARDED_PORT = True - Node.js(Express):需调用
app.set('trust proxy', true),再通过req.protocol和req.get('X-Forwarded-Port')获取 - 若后端返回绝对重定向(
Location: https://localhost:8080/),还需加proxy_redirect规则做响应头重写











