Nginx 反向代理路径:多一个斜杠为何请求不同

浏览器访问 /api 正常,经过反向代理以后后端却收到不同路径。很多此类问题来自 location 与 proxy_pass 的 URI 处理,不应首先怀疑数据库或鉴权。

edyang · 2020-02-13

浏览器访问 /api 正常,经过反向代理以后后端却收到不同路径。很多此类问题来自 location 与 proxy_pass 的 URI 处理,不应首先怀疑数据库或鉴权。

代理可以保留原 URI,也可以使用指定 URI 替换匹配前缀。尾部斜杠改变替换关系;应用还可能依赖 Host、客户端地址与协议头。路径路由、请求转发与响应跳转需要分别对照。

Nginx 反向代理路径:多一个斜杠为何请求不同:处理路径与验证条件

一、问题的范围与前提

浏览器所看到的页面、实际请求地址与服务器收到的路径要对应起来。页面来源、代理、缓存、Cookie 和连接生命周期分别影响行为。桌面浏览器、平板与嵌入式 WebView 可能具有不同访问条件,不能把某一端成功直接视为所有终端都已通过。

二、技术分析与方案取舍

例如浏览器请求 /api/items,配置 location /api/ 配合 proxy_pass http://127.0.0.1:8000/ 时,预期上游路径为 /items。若 proxy_pass 不带 URI,处理关系又不同。

应同时测试 /api/、具体资源、查询参数和后端跳转,避免只测根路径。后端如果知道自己位于某个 URL 前缀,还要确认资源链接和重定向使用同一约定,防止页面正常而静态资源或登录跳转失败。

实现时明确入口和 API 基址,页面或组件销毁后清理连接与定时器。版本更新需要考虑旧页面并存,错误提示保留网络、鉴权和依赖异常的区别。若采用代理,路径替换和协议头按预期上游核对,不能同时在多处随意拼接前缀。

三、实现与排查的顺序

  1. 列出浏览器请求与后端预期路径。
  2. 检查 location 的匹配顺序。
  3. 对照有无 URI 的 proxy_pass。
  4. 记录上游状态和实际请求路径。

按这个顺序保留中间结果,可以区分输入条件、处理过程和最终输出。前一阶段的条件不成立时,先解释对应错误,再继续后面的试验;单次返回成功不足以覆盖整条链路。

最小示例

1
2
3
4
5
location /api/ {
    proxy_pass http://127.0.0.1:8000/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
}

这个示例带 URI 的 proxy_pass 将匹配前缀替换为指定 URI,后端收到的路径需据此核对。若希望保留原路径,应使用相应配置并测试。请求地址、跳转和应用基址应保持一致,不能两边重复添加 api。

四、验证和结果解释

一组完整的排查资料应能展示请求方法、路径、响应状态与时间,以及相关后端记录。只展示一个登录失败截图,无法判断请求是否到达目标服务。共享记录时移除凭据和个人信息,仅保留非敏感字段、状态与必要结构。

需要验证的结果 保留的对照 不能由此推出的结论
普通路径与带查询参数请求都正确 固定输入与配置、对应输出 一次成功代表所有条件成功
不存在重复 api 前缀 中断前后状态与错误阶段 没有报错代表结果正确
重定向不会跳到错误域名或协议 恢复后的同条件复测 临时恢复代表根因已经消失

验证应覆盖首次打开、缓存命中、刷新、断网恢复与后台切换。连接状态和最后有效数据分别显示,旧数据不能因页面仍打开而永久看作实时。发布后的页面和静态资源还应逐项核对,不仅检查仓库文件是否存在。

五、适用边界与结论

不能通过同时修改前端基址与代理规则掩盖路径不一致。代理转发头应按可信入口配置,不能直接信任任意客户端提供的地址。

这条路径把“列出浏览器请求与后端预期路径”与“记录上游状态和实际请求路径”连在一起,中间保留可复查的条件。实施时优先确认“普通路径与带查询参数请求都正确”,再检查“重定向不会跳到错误域名或协议”;两者都满足,才能在当前样本与配置范围内评价方案。设备、数据或软件版本改变以后,相关假设需要重新验证。

参考资料