Ubuntu 22.04 上 nginx 把 /api/ 前缀反代到后端的根路径,配置写成 proxy_pass http://127.0.0.1:8080;,后端日志里请求路径一直带着 /api,接口全是 404。

一开始怀疑是「后端本身也配了 context-path,两层前缀叠在一起」,查了一圈,方向不对。

这类报错背后常见的原因有几处,逐个排除就行。proxy_pass 后面不带 URI 时,nginx 会把匹配到的原始路径整段转发过去。还有一种是location 用了 ^~ 前缀匹配但没有 rewrite,前缀自然留在路径里。

还有一种情况,用 rewrite 改路径时漏了 break,规则没生效就继续匹配。

第一件事是确认当前实际转发的路径

tail -20 /var/log/nginx/access.log | awk '{print $7}'

然后在 proxy_pass 后补上斜杠去掉前缀

printf 'location /api/ { proxy_pass http://127.0.0.1:8080/; }\n' > /etc/nginx/conf.d/api.conf && nginx -t && nginx -s reload

随后核对后端收到的路径是否正确

curl -s http://127.0.0.1/api/ping -o /dev/null -w '%{http_code}'

需要保留部分前缀时改用 rewrite

printf 'location /api/ { rewrite ^/api/(.*)$ /$1 break; proxy_pass http://127.0.0.1:8080; }\n' > /etc/nginx/conf.d/api.conf

别只看报错消失,验证要多做一步。后端日志里路径变成 /ping,curl 返回 200,接口文档里列出的地址逐条验证通过。

proxy_pass 带不带斜杠是两套转发语义,配错不会有任何告警;前缀重写优先用原样转发交给后端处理,前后端两边都改更容易乱。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189