nginx upstream不处理路径还原,关键在proxy_pass斜杠匹配、x-forwarded-*头透传和proxy_redirect重写响应头;斜杠不一致或头缺失会导致路径错乱、跳转失败。

Nginx 中 upstream 本身不参与路径还原,它只负责把请求转发给后端节点。真正影响客户端路径能否正确还原的,是 location 块里的 proxy_pass 配置、X-Forwarded-* 头透传、以及响应头重写(如 proxy_redirect)这三类机制。多级代理下路径错乱,90% 出在 proxy_pass 尾部斜杠和头信息缺失。
proxy_pass 斜杠规则必须对齐
location 和 proxy_pass 的末尾斜杠是否匹配,直接决定原始路径前缀是否被剥离:
location /api/ { proxy_pass http://backend/; }
请求/api/v1/user→ 后端收到/v1/userlocation /api/ { proxy_pass http://backend; }
请求/api/v1/user→ 后端收到/api/v1/userlocation /api { proxy_pass http://backend/api; }
请求/api/v1/user→ 后端收到/api/v1/user(注意:location 不带/,proxy_pass 也不能带/)错误组合如
location /api/ { proxy_pass http://backend; }或location /api { proxy_pass http://backend/; },会导致路径重复、缺失或双斜杠,后端解析失败。
多级代理中必须逐级透传关键头信息
每经过一级 Nginx,都需显式设置以下 header,否则后端无法还原原始访问上下文:
proxy_set_header Host $host;
防止后端生成跳转链接时用错域名(比如拼出http://backend/xxx)proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
把真实客户端 IP 追加到链路头中,避免被覆盖proxy_set_header X-Forwarded-Proto $scheme;
让后端知道原始请求是 HTTP 还是 HTTPS,用于生成安全跳转proxy_set_header X-Forwarded-Prefix /api;(可选但推荐)
显式声明前端代理路径前缀,供后端构造资源 URL 或 base href
后端返回 302 重定向时需主动修正 Location 头
upstream 模块不处理响应头,但 location 块中的 proxy_redirect 可以:
若后端返回
Location: http://10.0.4.120/dashboard,应重写为对外地址:proxy_redirect http://10.0.4.120/ $scheme://$host/api/;更通用的做法是用正则匹配任意内网地址并归一化:
proxy_redirect ~^https?://[^/]+(?::\d+)?/(.*)$ $scheme://$host/api/$1;如果后端返回的是相对路径(如
Location: /dashboard),且你代理的是/api/,则补上前缀:proxy_redirect / /api/;
HTML 页面内相对路径要兼容代理路径
静态 HTML 里写的 <script src="/js/app.js"></script> 在代理到 /api/ 下会变成请求 /api/js/app.js,但后端可能只提供 /js/app.js。解决方式有两种:
- 在 HTML 中添加
<base href="/api/">,让所有相对路径自动带上前缀 - 或用 Nginx 的
sub_filter动态替换:sub_filter '' '<base href="/api/">';sub_filter_once on;
不复杂但容易忽略











