在配置 Nginx 反向代理时,很多人会遇到一个困惑:代理配好了,访问域名却返回 404,而直连后端明明正常。本文用最小示例讲清 Nginx 反向代理返回 404 的三类常见成因——路径被改写、location 匹配错位、上游服务根路径不对——帮你把请求正确地转发到后端,避免配了 proxy_pass 却仍然 404 的尴尬。Nginx 反向代理本质是「按 location 把请求转发给上游」,理解路径拼接规则后,404 问题基本都能自己定位。当你能把这个转发链路讲给同事听时,网关配置的整体思路也就真正建立起来了,后续维护成本会明显下降。

先看结论
Nginx 反向代理返回 404 的核心,往往是「转发给上游的 URI 和你以为的不一样」。proxy_pass 末尾带不带斜杠,决定了 Nginx 是否把 location 匹配到的路径部分也拼到上游地址后。所以 404 大多来自路径被多拼一段、或少拼一段。把「location 匹配段」和「上游实际路径」对齐,大多数困惑就消失了。
一、最小场景与前置准备
前置只需两步:一台装好 Nginx 的 Linux 服务器,和一个能直连返回 200 的后端服务(如 127.0.0.1:8080)。很多困惑来自把 proxy_pass 当成了单纯「域名转发」。如果你刚开始系统学,可以先看 Nginx 入门指南 把配置结构理顺,再回头理解下面的例子。
下面是最基础的代理写法:
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
访问 /api/user 时,Nginx 会把 /api/ 这段去掉,向上游发 /user。proxy_pass 末尾的斜杠是关键,它触发「替换 location 匹配段」的语义。
二、原因一:proxy_pass 末尾斜杠导致路径被改写
最常见的困惑是:为什么我访问 /api/user 后端却收到 /user,于是返回 404?根本原因是 proxy_pass 带尾斜杠时会把 location 匹配到的 /api/ 整段替换掉。Nginx 反向代理的路径拼接规则在这里起决定作用。
正确做法是按上游真实路径决定斜杠。例如上游根路径就是 /api/user:
location /api/ {
proxy_pass http://127.0.0.1:8080; # 不带尾斜杠,保留 /api/ 前缀
}
这样上游收到的是 /api/user,与后端路由一致。记住,尾斜杠决定「是否剥离匹配段」。另一个容易忽略的边界是:若 location 用了正则 ~,proxy_pass 里不能带 URI 部分,否则语法报错。
三、原因二:location 匹配错位选错块
第二个困惑是请求根本没进你以为的那个 location。通常是因为 location 优先级:精确 = 最高,普通前缀次之,正则 ~ 会插队。一个更具体的正则把你的请求抢走了,于是转发出去的是别的路径,自然 404。
调整方式是明确优先级:
location = /api/health { return 200 "ok"; } # 精确优先
location /api/ { proxy_pass http://127.0.0.1:8080/; }
明确每个 location 的匹配规则,是请求落到正确块的前提。如果你想看更多网关配置的实战写法,可以参考 Nginxsysc 教程 里 location 一章。
四、原因三:上游服务根路径不对
第三个困惑来自上游自身。即使 Nginx 转发正确,上游服务如果只监听子路径(如 /app),而 Nginx 转过去的是根 /,上游也会 404。这是「Nginx 没错、后端路由没对上」的典型。
WebSocket 或带路径前缀的上游更容易踩坑
如果上游是带前缀的服务(如 /api/v1),而 Nginx 用带尾斜杠的 proxy_pass 把 /api/ 剥掉了,转过去就少了前缀,上游自然 404。这类场景要么 upstream 本身监听根路径,要么用 rewrite 把前缀补回来,而不是只调 proxy_pass 斜杠。
失败处理:当 Nginx 日志显示已 200 连上上游却仍 404,问题在后端。验证方法很简单:用 curl http://127.0.0.1:8080/你的路径 直连上游;预期返回 200,若直连也 404 则修后端路由,再重新验证直到绿灯。未在本机执行,上述为 Nginx 官方文档描述的预期行为。
还有一个常见坑值得单独提醒:很多人只看浏览器报错,不查日志就瞎改。务必打开 access.log(或 error.log)确认 Nginx 到底向上游发了什么 URI、返回码是多少;如果日志里上游返回的是 404,问题基本在后端的路径,而不是 proxy_pass 写法。把"安装→配置→运行→检查→失败→修复→验证"固化成固定动作,同类问题排查会快很多。另外 proxy_set_header Host $host; 这类头设置若漏掉,某些上游会按默认 Host 找不到资源而 404,排查时也要一并看。
动手核对清单
- 安装:确认 Nginx 已安装,
nginx -v能输出版本。 - 配置:按上游真实路径决定 proxy_pass 尾斜杠。
- 运行:
nginx -t校验后reload生效。 - 检查:用
curl直连上游确认路径存在。 - 预期:预期上游收到与路由一致的 URI。
- 失败:404 先查 access.log 里的真实转发路径。
- 修复:按报错修正斜杠或 location 优先级,重新验证。
- 适用边界:正则 location 的 proxy_pass 不能带 URI 段。


总结
Nginx 反向代理返回 404 的困惑大多源于路径拼接和匹配优先级。守住所见即所得的三条线——尾斜杠决定路径改写、location 优先级要对、直连上游验证后端路径——请求就能稳定转发到正确位置,404 也会清晰很多。一句话记忆:先查 access.log 看真实转发 URI,再直连上游确认后端路径,最后才动 proxy_pass 斜杠。这个顺序走一遍,绝大多数 404 都能定位。
常见问题
Q:为什么加斜杠后后端收到的路径变了?
答:因为 proxy_pass 带尾斜杠时会把 location 匹配到的路径段(如 /api/)整体替换掉。不带尾斜杠则保留该前缀,按上游真实路由选择即可。
Q:配置看起来对,请求却不进这个 location?
答:被更高优先级的 location 抢走了,比如精确 = 或正则 ~。用 curl 配合 access.log 看实际命中的块,再调整 location 写法与顺序。
Q:Nginx 连上上游了还是 404 怎么办?
答:问题在后端路由。用 curl 直连上游同路径验证,若直连也 404,说明是后端根路径或路由没对上,而不是 Nginx 的问题。
Q:加了反向代理后静态资源也 404 了?
答:多半是 location 把静态请求也转给了上游,而上游不提供这些文件。静态资源(js/css/图片)应当用独立 location 配 root 或 alias 在 Nginx 本地返回,只有真正的接口请求才走 proxy_pass。把静态和接口分开配置,404 会少一大半。
Q:proxy_pass 后面能带路径吗(比如 http://up/app/)?
答:可以,而且带路径时 Nginx 会把 location 匹配段替换成你写的这段路径,相当于同时做了一次重写。这常用于把 /api/ 映射到上游的 /app/,但要小心多一层路径拼接,确认上游收到的 URI 和你预期一致,避免又掉进 404。

TRAE-AI编程



