proxy_redirect用于将后端返回的301/302响应头中location地址(如http://192.168.1.10:8080/login)替换为公网可访问地址(如https://example.com/login),仅重写响应头、不执行跳转;需配合curl -i验证原始location类型,按绝对url、协议升级、子路径或正则动态匹配配置对应规则,且必须置于proxy_pass之后,同步设置host、x-forwarded-proto等请求头,并通过error_log info和curl -i双重验证生效。

proxy_redirect 不是让 Nginx 自己跳转,而是把后端返回的 301/302 响应头里的 Location 地址,从内网地址(比如 http://192.168.1.10:8080/login)替换成用户能打开的公网地址(比如 https://example.com/login)。它只改响应头,不碰请求路径,也不执行跳转动作。
先看清后端实际返回什么
别靠猜,用 curl 直接抓真实响应头:
curl -I https://your-domain.com/login- 重点看返回里有没有
Location:行 - 判断它是绝对 URL(含
http://或内网 IP)还是相对路径(如/dashboard) - 如果看到
Location: http://10.0.2.5:3000/callback这类,说明必须替换协议、IP 和端口
按 Location 类型写 proxy_redirect 规则
规则必须写在 location 块里,且放在 proxy_pass 之后:
- 后端固定返回
http://192.168.1.100:8080/:proxy_redirect http://192.168.1.100:8080/ $scheme://$host/; - 只统一协议(后端返回
http://,但你要https://):proxy_redirect http:// https://; - 子路径代理场景(如
location /admin/代理到后端根,后端返回/login):proxy_redirect / /admin/; - 动态适配任意内网地址(推荐容器或云环境):
proxy_redirect ~^http://[^/]+(?::\d+)?(/.*)?$ $scheme://$host$1;
光改 Location 不行,还得传真实请求信息
否则后端下次生成重定向时,还会出同样问题:
-
proxy_set_header Host $host;—— 防止后端误用 localhost 或内网域名 -
proxy_set_header X-Forwarded-Proto $scheme;—— 明确告知 HTTP 还是 HTTPS,避免协议降级 -
proxy_set_header X-Real-IP $remote_addr;和X-Forwarded-For $proxy_add_x_forwarded_for;—— 保留客户端真实 IP
验证是否真正生效
配置完 reload 前,务必实测:
- 再跑一次
curl -I https://your-domain.com/login,确认Location:已变成可访问的公网地址 - 开启 error_log 到 info 级别,能看到匹配和替换日志:
error_log /var/log/nginx/error.log info; - 常见失败原因:指令位置错(没放在 proxy_pass 后)、漏分号、正则多空格、变量在非 HTTPS 块中不可用











