proxy_redirect用于修正后端返回的Location/Refresh响应头中的内网地址为客户端可访问的外网地址。其核心作用是将如http://10.0.1.100:8080/success重写为https://example.com/success,避免CDN透传内网跳转导致失败。

当 Nginx 作为反向代理接入 CDN(如 Cloudflare、阿里云 CDN、腾讯云 CDN 等)时,后端应用(如 PHP、Node.js、Java 应用)返回 301/302 跳转响应,其 Location 响应头中的地址通常是内部地址(如 http://10.0.1.100:8080/login 或 http://localhost:3000/callback),CDN 回源获取该响应后,若不加处理就直接透传给客户端,会导致浏览器跳转到不可访问的内网地址或错误端口,从而跳转失败。
proxy_redirect 的作用就是重写 Location 响应头
proxy_redirect 指令用于修改上游服务器返回的 Location 和 Refresh 响应头中的 URL,使其适配客户端实际访问的域名和协议。它不是用来改写请求路径,而是专门针对跳转响应头的“出站修正”。
基本语法:
proxy_redirect <旧前缀> <新前缀>;
例如,后端返回:Location: http://10.0.1.100:8080/success,而用户实际通过 https://example.com 访问,则需将其重写为:Location: https://example.com/success。
常见配置方式(按场景选择)
-
关闭自动重写(慎用):
proxy_redirect off;
适用于后端已返回正确外网地址,或你完全自行控制跳转逻辑,不需要 Nginx 干预。 -
精确匹配并替换(推荐初学者使用):
proxy_redirect http://10.0.1.100:8080/ https://example.com/;
将所有以http://10.0.1.100:8080/开头的 Location 地址,替换成https://example.com/。注意末尾斜杠必须一致,否则不匹配。 -
使用正则灵活匹配(应对多环境/多端口):
proxy_redirect ~^http://[^/]+(?::\d+)?/(.*)$ https://example.com/$1;
该正则忽略原始协议、主机、端口,只提取路径部分$1,再拼接到目标域名下,适合后端动态返回各种内网地址的场景。 -
适配 HTTP/HTTPS 自动识别(结合 $scheme):
若希望根据客户端真实协议自动选择http或https,需配合proxy_set_header X-Forwarded-Proto $scheme;,并在后端应用中读取该 header 构造跳转地址;此时 Nginx 侧可设为:proxy_redirect http://10.0.1.100:8080/ /;
表示将内网路径前缀替换为相对路径(即去掉 host 部分),由浏览器基于当前页面协议和域名补全,前提是后端返回的是绝对 URL 且 Nginx 能正确剥离。
CDN 场景下的关键注意事项
- 确保 CDN 回源 Host 头正确(如
Host: example.com),否则$host或$server_name变量可能取错值;可在 Nginx 中用proxy_set_header Host $host;显式传递。 - 如果 CDN 启用了“强制 HTTPS”或“HTTP 转 HTTPS”,但回源走的是 HTTP,那么后端看到的是
X-Forwarded-Proto: https,它应据此生成https://开头的 Location;此时 Nginx 的proxy_redirect应与后端输出一致,避免双重修正。 -
proxy_redirect默认只处理Location和Refresh头,不处理Content-Location或自定义跳转头;如有特殊需求,需用sub_filter或 Lua 模块干预响应体。 - 调试时可用
curl -I查看响应头变化,并开启error_log /path/to/log debug;(配合debug编译模块)观察 proxy_redirect 是否命中匹配规则。
一个典型 CDN + Nginx + Spring Boot 示例
假设用户访问 https://app.example.com/login,CDN 回源到 Nginx,Nginx 代理至 http://172.16.0.5:8080;Spring Boot 返回 Location: http://172.16.0.5:8080/oauth2/authorization/github。
Nginx 配置片段:
location / {
proxy_pass http://172.16.0.5:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
<pre class='brush:php;toolbar:false;'># 修正跳转地址:把内网地址换成用户实际访问的 HTTPS 地址
proxy_redirect http://172.16.0.5:8080/ https://app.example.com/;}
这样,用户最终收到的响应头就是:Location: https://app.example.com/oauth2/authorization/github,跳转正常。










