port_in_redirect用于控制Nginx自身生成重定向时Location头是否含端口,默认on;off时一律省略端口,仅影响Nginx主动重定向(如return、rewrite),后端重定向需用proxy_redirect处理。

当 Nginx 作为反向代理时,后端服务(如应用服务器)可能运行在非标准端口(例如 8080、3000),而用户通过 80 或 443 访问。此时若后端返回 302 重定向响应(如登录跳转、路径修正),其 Location 头中常包含原始后端端口(如 http://example.com:8080/login),这显然不友好且暴露内部结构。
port_in_redirect 是 Nginx http、server 或 location 块中的指令,用于控制是否在重定向响应的 Location 头中保留端口号。它的作用对象是 Nginx 自己生成的重定向(比如 return 301、rewrite ... redirect),**不是**后端返回的重定向 —— 后者需用 proxy_redirect 处理。
port_in_redirect 的行为逻辑
该指令默认值为 on。这意味着:
- 当 Nginx 主动发起重定向(如
return 302 /new;),且当前请求是通过非标准端口(如 :8080)进入时,生成的Location: http://$host:8080/new会带端口; - 若请求走的是标准端口(80/443),即使设为 on,Nginx 也不会显式写出端口(HTTP 规范要求省略);
- 设为 off 后,Nginx 主动重定向时一律不带端口,只写
http://$host/path(或https://$host/path,取决于$scheme)。
典型配置示例
常见于前端代理场景,避免用户看到内部端口:
http {
port_in_redirect off; # 全局关闭,适用于多数反代场景
<pre class="brush:php;toolbar:false;">server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
# 注意:后端重定向仍需 proxy_redirect 修正
proxy_redirect http://127.0.0.1:3000/ /;
}
}}
也可在 server 或 location 块内单独控制,实现更细粒度策略。
与 proxy_redirect 的分工关系
务必区分两者职责:
-
port_in_redirect:仅影响 Nginx 自己生成的重定向(如rewrite ^/old$ /new redirect;); -
proxy_redirect:专门改写 后端返回的重定向响应头(如 Rails 返回Location: http://localhost:3000/success),将其映射为对外域名和端口; - 二者常配合使用:一个管“自己发的”,一个管“后端发的”。
实际调试建议
验证是否生效,可构造一个明确由 Nginx 发起的重定向:
- 在配置中添加:
location /test-redirect { return 302 /target; }; - 用
curl -I http://your-domain/test-redirect查看Location值; - 对比
port_in_redirect on/off下的输出差异(尤其注意非 80/443 端口访问时)。
注意:浏览器地址栏最终显示受 Location 响应头直接控制,该头必须符合协议规范(如 HTTPS 请求下不应返回 HTTP 地址),否则可能被拒绝跳转。


















