proxy_redirect 不支持变量直接嵌入 old_prefix/new_prefix,需用正则匹配路径并结合 replacement 中的 $scheme/$host(1.19.2+)实现自动修正,旧版本须硬编码;缓存场景需禁用 301/302 缓存并规范后端跳转。

proxy_redirect 本身不支持变量(如 $host、$scheme)直接嵌入 old_prefix 或 new_prefix 参数中——Nginx 官方明确限制该指令只接受字面量字符串或正则表达式,变量在 proxy_redirect 中会被当作普通文本处理,不会展开。因此,“结合变量实现全路径自动修正”不能靠 proxy_redirect 动态插值完成,而需通过合理设计静态规则 + 正则匹配 + 协议/域名一致性保障来达成等效效果。
下面分三部分讲清楚怎么做:
一、为什么不能直接用 $host 或 $scheme 在 proxy_redirect 里
-
proxy_redirect http://$host:8080/ https://$host/;❌
这行配置不会解析变量,Nginx 启动时会报错invalid URL prefix,或静默忽略,导致重定向失效。 - 所有
proxy_redirect的old_prefix和new_prefix必须是确定的、可精确匹配的字符串(如http://10.0.1.5:8080/)或带~的 PCRE 正则(如~^https://www.php.cn/link/77c67b0f0e59ae3e0e2b4ba9e249b9d8+)?/(.*)$)。
二、实现“全路径自动修正”的可行方案
核心思路:用正则提取路径,用固定新前缀适配多环境,再靠请求头确保后端生成正确跳转源
-
✅ 推荐正则写法(覆盖不同内网地址+端口):
location / { proxy_pass http://backend:8080/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; # 提取任意内网绝对URL的路径部分,重写为当前公网协议+域名+根路径 proxy_redirect ~^https://www.php.cn/link/77c67b0f0e59ae3e0e2b4ba9e249b9d8+)?/(.*)$ $scheme://$host/$1; }⚠️ 注意:
$scheme和$host在这里能用,是因为它出现在new_prefix的正则替换捕获组$1之后的位置,且 Nginx 1.19.2+ 支持在proxy_redirect的 replacement 中使用这些变量(仅限于 replacement 部分,old_prefix 仍不可变)。这是关键兼容点,旧版本需降级为硬编码域名。 -
✅ 若需兼容老版本 Nginx(
# 生产环境 proxy_redirect ~^https://www.php.cn/link/77c67b0f0e59ae3e0e2b4ba9e249b9d8+)?/(.*)$ https://app.example.com/$1;
测试环境
proxy_redirect ~^https://www.php.cn/link/77c67b0f0e59ae3e0e2b4ba9e249b9d8+)?/(.*)$ https://www.php.cn/link/f9145ca6d153a22f2c344f15ce8034f6;
### 三、缓存代理场景下的协同要点(防止缓存污染跳转) 当 Nginx 同时做反向代理和响应缓存(如 `proxy_cache`)时,`Location` 头若被缓存,后续用户可能拿到过期/错域的跳转地址。必须: - 强制不缓存含 `Location` 响应头的 301/302 响应: ```nginx proxy_cache_bypass $http_pragma $http_authorization; proxy_no_cache $http_pragma $http_authorization; # 关键:对重定向响应禁用缓存 proxy_cache_valid 301 302 0;
确保后端不自行拼接完整跳转 URL(应优先返回相对路径
/dashboard),减少proxy_redirect匹配负担;若必须返回绝对地址,统一由 Nginx 通过X-Forwarded-*头告知后端真实访问上下文,使其生成https://$host/xxx——这样甚至可省掉proxy_redirect。-
验证是否生效:
curl -I https://app.example.com/login # 应看到:Location: https://app.example.com/dashboard(而非内网地址或带端口)
本质上,“自动修正”不是靠变量实时计算,而是靠正则泛匹配 + 变量安全注入 replacement + 后端配合生成规范跳转。只要这三层对齐,就能在缓存、HTTPS、多子域等复杂场景下稳定工作。











