nginx反代时添加上下文路径,导致资源404

当我使用 Nginx 进行反向代理服务时,通常的做法是为每个服务分配一个 子域名,这样每个服务都可以从 / 开始处理 URI。比如以下配置:

server {
    listen 443 ssl;

    server_name share.example.cn;

    ssl_certificate      "/etc/nginx/conf.d/cert/example.cn/cert.pem";
    ssl_certificate_key  "/etc/nginx/conf.d/cert/example.cn/key.pem";

    location / {
        proxy_pass http://shlink:8080/;
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 443 ssl;

    server_name link.example.cn;

    ssl_certificate      "/etc/nginx/conf.d/cert/example.cn/cert.pem";
    ssl_certificate_key  "/etc/nginx/conf.d/cert/example.cn/key.pem";

    location / {
        alias /usr/share/nginx/html/link.example.cn/;
        index index.html;
    }
}

但是这个配置有点不方便,因为这是一个前后端分离的服务,使用两个子域名不仅不便管理,还需要处理跨域问题。因此,我想把它们放在 同一个子域名 下。

于是,我修改了配置,简单地为管理端新增了 /admin/ 的上下文路径:

server {
    listen 443 ssl;

    server_name link.example.cn;

    ssl_certificate      "/etc/nginx/conf.d/cert/example.cn/cert.pem";
    ssl_certificate_key  "/etc/nginx/conf.d/cert/example.cn/key.pem";

    location / {
        proxy_pass http://shlink:8080/;
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /admin/ {
        alias /usr/share/nginx/html/link.example.cn/;
        index index.html;
    }
}

然而,这样的配置引入了一个问题:新增上下文的上游服务无法识别自己需要加上 /admin 前缀,导致虽然 index.html 可以访问,但请求相关静态资源时,路径仍然是没有 /admin 的,比如 /server/setting,从而导致路由失败。因此,这个配置无法满足需求。

前提是我 无法 修改上游服务的配置,或者我只有打包好的静态资源文件。

在这种情况下,我是否有办法将两个服务反代到同一个子域名上呢?这个问题困扰了我很久,希望能够得到帮助。

10 个赞

需要动前端源代码的:rofl::rofl:,有时候静态资源正常了,路由也有可能不正常,上个月某几个项目就合并到一个域名下,大改了一顿,ps一句前端项目用的vue​:face_holding_back_tears::face_holding_back_tears:

好吧,那就老老实实的两个子域名好了

1 个赞

子域名是最方便的:rofl::rofl:,子路径处理不好真的很折腾人

1 个赞

都前后端分离了,为啥不能通过路径location去做,前后端分离搞的路径还一样?那也是人才

没理解你说的什么意思。我的情景是

前提是我 无法 修改上游服务的配置,或者我只有打包好的静态资源文件。

我认为这个需求是有意义的,在不改变这个需求的前提下如果有解决方案可以分享一下。

换个思路,前端用/匹配,后端加子路径试试

前端有多个呢怎么匹配

这样的话也是需要在前端代码上修改后端的请求uri,我也翻了一下其它论坛上的相关文章。基本上没有好的解决方法

发自我的 iPhone