You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx Proxy Pass问题排查:Docker、React与Express环境

问题分析与解决方案

我来帮你拆解下为什么只有加尾斜杠才能正常工作:

当你调用process.env.PUBLIC_URL + "/api"时,最终请求路径是/todos/api,经过入口Nginx的rewrite后,传给二级Nginx的路径是/api(不带尾斜杠)。而你二级Nginx里的rewrite /api/(.*) /$1 break;规则只会匹配带有/api/后缀的路径(比如/api/xxx),对于单纯的/api请求,这条rewrite完全不会触发。此时proxy_pass到todoserver时,请求路径还是/api,而你的Express API根路由是/,自然就匹配不上了。

而当你加了尾斜杠变成/api/时,入口Nginx转成/api/,二级Nginx的rewrite规则命中,把路径改成/,刚好匹配Express的根路由,所以能正常工作。

接下来给你两个可行的解决方案,任选其一即可:

方案一:修改二级Nginx的rewrite规则,兼容带/不带尾斜杠的请求

把二级Nginx中/api的location块改成这样:

location /api {
    # 匹配/api 或/api/xxx的请求,统一重写为对应的路径(/ 或/xxx)
    rewrite ^/api(/.*)?$ $1 break;
    proxy_pass http://todoserver/;
    # 建议加上这些proxy头,避免Express端获取不到正确的请求信息
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

这个正则^/api(/.*)?$会匹配两种情况:

  • 精确的/api:此时$1为空,rewrite后路径是/
  • api/xxx:此时$1是/xxx,rewrite后路径是/xxx

这样不管请求带不带尾斜杠,都能正确映射到Express的对应路由。

方案二:让Nginx自动处理尾斜杠重定向(可选)

如果你不介意浏览器端有一次301重定向,可以在二级Nginx的/apilocation里先加一条重定向规则,把不带尾斜杠的请求转成带尾斜杠的:

location /api {
    # 先把/api重定向到/api/,这样后续的rewrite规则就能正常触发
    rewrite ^/api$ /api/ permanent;
    rewrite /api/(.*) /$1 break;
    proxy_pass http://todoserver/;
    # 同样加上必要的proxy头
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

这个方案的好处是不用修改rewrite的匹配逻辑,但缺点是会多一次重定向请求,适合对重定向不敏感的场景。

额外建议:优化入口Nginx的配置

你的入口Nginx/todos的location里用了rewrite /todos/(.*) /$1 break;,其实可以改成更严谨的正则匹配,避免一些边缘情况:

location ^~ /todos {
    rewrite ^/todos(/.*)?$ $1 break;
    proxy_intercept_errors on;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://todosnginx/;
}

用^~ /todos可以让这个location优先匹配,避免和其他可能的location规则冲突,同时rewrite规则也兼容/todos和/todos/xxx的请求。

最后,修改完配置后,记得重启对应的Nginx容器,让配置生效哦!

内容的提问来源于stack exchange,提问作者Raph117

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 10:47:53