nginx需用proxy_redirect重写302响应的location头,避免内网地址暴露;同时透传host、x-forwarded-proto等头使后端生成正确跳转,并可选proxy_intercept_errors接管跳转以统一加cors等头。

后端服务返回 302 时,Location 响应头常含内网地址(如 http://127.0.0.1:8080/login)或错误路径前缀,导致浏览器跳转到不可达地址——这就是“域名漂移”。解决核心是让 Nginx 在转发响应前,主动重写 Location 头为目标公网地址,而不是透传原始值。
用 proxy_redirect 修正 Location 前缀
该指令专用于改写 301/302 响应中的 Location、Refresh 和 Content-Location 头。必须写在 location 块内,且与 proxy_pass 配套使用:
- 若后端返回
Location: http://localhost:8080/dashboard,而你希望它变成https://example.com/dashboard,写:proxy_redirect http://localhost:8080/ /; - 若代理路径为
/admin/,后端返回的是根路径跳转(如/login),但用户实际访问的是/admin/login,则补上前缀:proxy_redirect / /admin/;(注意末尾斜杠表示“替换整个匹配路径”) - 支持正则动态适配多种内网地址(Nginx ≥ 1.11.8):
proxy_redirect ~^http://[^/]+(/.*)$ $scheme://$host$1;
传递真实请求上下文,预防源头出错
很多后端(如 Spring Boot、Django)会根据收到的请求头自动生成跳转地址。如果 Nginx 不传递关键信息,后端下次仍可能生成内网地址:
-
proxy_set_header Host $host;:避免后端误读 Host 为localhost或 IP -
proxy_set_header X-Forwarded-Proto $scheme;:告诉后端当前是 HTTP 还是 HTTPS,防止硬写http:// -
proxy_set_header X-Real-IP $remote_addr;和X-Forwarded-For $proxy_add_x_forwarded_for;:保障日志和安全逻辑准确
拦截并接管 302(进阶可控方案)
当需要统一加 CORS 头、或跳转目标仍在同一域名下时,可让 Nginx 拦截 302 并自行发起跳转,不把原始 Location 透给浏览器:
- 启用拦截:
proxy_intercept_errors on;error_page 301 302 = @handle_redirect; - 定义跳转处理块:
@handle_redirect {<br> add_header Access-Control-Allow-Origin "$http_origin" always;<br> add_header Access-Control-Allow-Credentials "true" always;<br> return 302 $sent_http_location;<br>}
验证是否生效的实操方式
别只看配置是否写对,要确认响应头真正被修改:
- 用
curl -I https://example.com/some-path查看返回的Location:是否已是公网地址、协议正确、路径完整 - 开启 debug 日志临时排查:
error_log /var/log/nginx/error.log debug;,搜索proxy_redirect相关输出 - 检查 Nginx 是否加载了
http_ssl_module(HTTPS 场景必需)和http_proxy_module











