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