请教一个 nginx 转发的问题

54 天前
 ShihanW

请问 V 友,nginx 如何使用路由转发不同的服务啊,比如机器上有两个服务,一个部署在 8080 端口(假设服务名为 a ),另一个在 8888 (服务名 b ),我的预期是分别设置/a 和/b 用以转发这两服务,并且它们的子路由也要转发,例如它们都有登陆,就分别为/a/login/b/login,但是我在访问/a 页面时点击登陆,浏览器路由就自动变成/login了,忽略了/a,这要这么办呢,难道我还要在 nginx 里对它们的子路由单独设置转发规则吗。

我现在是这样配置的

{
    listen 443;
    
    location /a {
        proxy_pass http://localhost:8080;
    }
    
    location /b {
        proxy_pass http://localhost:8888;
    }
}

1642 次点击
所在节点    NGINX
14 条回复
klo424
54 天前
GPT 的答案

```bash
server {
listen 80;
server_name example.com;

location /a/ {
proxy_pass http://localhost:8080/;
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;

# 如果服务 a 使用相对路径构建链接,需要进行重写
# rewrite ^/a/(.*)$ /$1 break;
}

location /b/ {
proxy_pass http://localhost:8888/;
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;

# 如果服务 b 使用相对路径构建链接,需要进行重写
# rewrite ^/b/(.*)$ /$1 break;
}
}
```
iseki
54 天前
这个问题要程序自己处理干净,尽量不假设自己一定在根,不然只能采用古老的重写页面内链的办法了(但很遗憾,这在现代复杂 Web 应用场景下不工作)。
现实中很多应用是不支持把自己配置到非根位置的…这就没太好的办法了。
google2020
54 天前
因为 a 前端路由的 root 还是 /,反代并不会改变代码,所以访问 root+/login 的时候还是 /login ,而不是 /a/login

你可以改变 a 的代码,把 root 改成 /a ,或者添加 root 变量,然后在 nginx 反代代码里用 sub_filter 替换
Puteulanus
54 天前
这个得你后端支持动态的路径,或者支持配置 url prefix ,不然它返回一个 /login 的 302 或者 a 标签给前端,nginx 要管这个得上专门的反代模块用规则去替换后端返回的内容了
NotFoundEgg
54 天前
{
listen 443;

location /a/ {
proxy_pass http://localhost:8080/a/;
}

location /b/ {
proxy_pass http://localhost:8888/b/;
}
}
oranges0196
54 天前
按目前已有信息,赞同 2 楼的答案。
你要先确定好自己的前端项目 a 的跳转地址是不是想要的 example.com/a/login ,然后再看 nginx 的路由。
虽然 nginx 也有办法实现 a 项目跳转 example.com/login 路由到 a ,b 项目跳转到跳转 example.com/login 路由到 b ,但是不建议这样做
IvanLi127
54 天前
web 应用得支持部署在子目录才行,先去确认吧
Curtion
54 天前
这种需要 A 服务的代码处理,它在跳转过程中不能使用绝对路径
wheat0r
54 天前
现在的应用还不让放到子目录的话,让开发自裁吧
ShihanW
54 天前
@Curtion
@oranges0196
@iseki
@google2020
@Curtion
因为部署的服务都是第三方,无法获取源码修改内链😭
ShihanW
54 天前
感谢大家的回复
dropdatabase
54 天前
@ShihanW 你可以用域名区分 就没这个问题了
wenyiduo8
53 天前
核实下你的语句,按我的理解,你的 proxy_pass http://localhost:8080;
8080 后面有 / 才会出现这种情况啊。
没有/
/a/login 会路由到 http://localhost:8080/a/login
有/
/a/login 会路由到 http://localhost:8080/login
ShihanW
53 天前
@dropdatabase
你说的没错,不过前提是子服务的前端链接的地址不能是从根路由开始才行。
----------分割-----------------
@wenyiduo8
我找到区分办法了,部署的 a 和 b 两个服务都自定义 base_url ,然后结合 @dropdatabase 提出的建议,完美解决我的需求。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1024262

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX