proxy_redirect用于重写后端返回的Location响应头,将其替换为客户端可访问的公网地址;需配合proxy_set_header传递X-Forwarded-Proto、Host等头,确保后端生成正确跳转,并通过正则或字面量规则精准匹配替换。

核心不是让 Nginx “跳转”,而是把后端返回的 Location 响应头改成客户端能访问的地址。后端通常按自己监听地址生成重定向(比如 http://10.0.1.5:8080/login),直接透传会导致浏览器跳到内网或错误端口,打不开。
必须配置 proxy_redirect 重写 Location 头
这是最直接有效的手段。Nginx 不会自动改写,得明确告诉它怎么替换:
- 如果后端返回
http://backend:8080/path,而你希望用户跳到https://example.com/path,写:proxy_redirect http://backend:8080/ https://example.com/; - 更通用的做法是匹配所有 HTTP/HTTPS 开头的地址,统一换成当前请求的协议和域名:
proxy_redirect ~^https?://[^/]+(/.*)$ $scheme://$host$1; - 不想自动改写、只处理特定规则?先关掉默认行为:
proxy_redirect off;
再逐条加映射,例如:proxy_redirect http://localhost:8000/ /;proxy_redirect https://internal-api/ /api/;
透传 X-Forwarded-Proto 让后端知道真实协议
很多框架(Spring Boot、Django、Next.js)靠这个头判断是否该用 HTTPS 生成重定向。不传或传错,后端可能坚持返回 http:// 地址,引发跳转死循环:
- 在
location块里加:proxy_set_header X-Forwarded-Proto $scheme;
($scheme自动取值http或https,别硬写死) - 后端必须启用对应解析:Spring Boot 配
server.forward-headers-strategy=framework;Django 配SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') - 确认后端信任 Nginx 的 IP,否则忽略这些头。比如 Spring Boot 要设
server.tomcat.remoteip.proxies-header=x-forwarded-by并填入 Nginx 服务器真实 IP 段
同步修正 Host 和真实客户端 IP
Host 头影响后端路由和重定向构造;X-Real-IP/X-Forwarded-For 决定后端看到谁发起的请求:
- 保持原始 Host(不含端口):
proxy_set_header Host $host;
避免用$http_host,它可能带:443,部分后端拒绝处理 - 传递真实 IP:
proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 若后端部署在子路径(如
/admin/),且返回相对路径/login,但用户实际访问的是/admin/login,需用:proxy_redirect / /admin/;
特殊场景:处理 307 临时重定向
Nginx 默认不跟随 307,而是原样返回给浏览器。如果后端用 307 做内部跳转,又返回内网地址,就得让 Nginx 主动“再发一次请求”:
- 启用拦截:
proxy_intercept_errors on;error_page 307 = @handle_307; - 在
@handle_307中用响应头里的地址重发:location @handle_307 { proxy_pass $sent_http_location; } - 确保
$sent_http_location是 Nginx 能直连的地址(如http://backend-svc/xxx)。如果是http://localhost:8080/xxx,得先用map或额外rewrite替换掉


















