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

Nginx反向代理自定义Location无法加载静态资源问题求助

Nginx反向代理自定义Location无法加载静态资源问题求助

兄弟,我看了你遇到的问题——在同一个子域名下用/test/路径反向代理到另一个容器,但静态资源全是404,这个坑我之前也踩过,咱们来一步步捋清楚问题出在哪,以及怎么解决。

首先分析下你当前的情况:

  • 你设置了location /test/来代理到另一个容器的4123端口,但浏览器请求https://foo.bar.baz/test/styles.css时返回404,核心原因有两个可能:
    1. 路径匹配问题:你的location /test/是带结尾斜杠的,Nginx只会匹配以/test/开头的路径(比如/test/xxx),但/test/styles.css并不符合这个规则,会被转到根路径的location /里,而根路径指向的是主站点容器,自然找不到这个资源。
    2. 后端URI不匹配:就算路径匹配上了,后端容器的资源是放在根路径下的(比如http://dockercontainer:4123/styles.css),但当前请求传递给后端的是/test/styles.css,后端找不到这个路径的资源,也会返回404。

接下来给你两个针对性的解决方案,你可以根据实际情况选:

方案一:重写URI,让后端收到根路径请求

这个方法是在代理时把/test/前缀去掉,让后端容器收到的是它期望的根路径请求。修改你的location /test/配置如下:

location ^~ /test/ {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Scheme $scheme;
    proxy_set_header X-Forwarded-Proto  $scheme;
    proxy_set_header X-Forwarded-For    $remote_addr;
    proxy_set_header X-Real-IP          $remote_addr;

    # 关键:把/test/开头的路径重写为去掉前缀的格式
    rewrite ^/test/(.*)$ /$1 break;

    # 这里注意!你当前写的proxy_pass是http://foo.bar.baz:4123/,应该换成Docker容器的内部地址
    # 比如http://your-another-container:4123/,不然可能会触发循环代理
    proxy_pass       http://your-another-container:4123/;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;
}

解释下:

  • ^~ /test/是强制匹配这个路径,避免被其他正则location抢占;
  • rewrite规则把/test/styles.css转换成/styles.css后再传递给后端,这样后端就能找到对应的静态资源了。

方案二:修改页面内的资源路径(适合后端无法修改的场景)

如果后端网站生成的资源是绝对路径(比如<link href="/styles.css">),浏览器会自动拼成https://foo.bar.baz/styles.css,这时候就算用了方案一,这个请求还是会走到根路径的location /。这时候可以用Nginx的sub_filter模块来替换页面里的资源链接,让它们都加上/test/前缀:

location ^~ /test/ {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Scheme $scheme;
    proxy_set_header X-Forwarded-Proto  $scheme;
    proxy_set_header X-Forwarded-For    $remote_addr;
    proxy_set_header X-Real-IP          $remote_addr;

    proxy_pass       http://your-another-container:4123/;

    # 替换页面中所有绝对路径的资源链接,加上/test/前缀
    sub_filter 'href="/' 'href="/test/';
    sub_filter 'src="/' 'src="/test/';
    # 开启全局替换,不然只替换第一个匹配项
    sub_filter_once off;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;
}

这个方法会在返回给浏览器的页面里,把所有以/开头的资源链接替换成/test/开头,这样浏览器就会请求https://foo.bar.baz/test/styles.css,而这个路径会被你的location /test/捕获并正确代理到后端。

最后提醒你一下:一定要把proxy_pass里的http://foo.bar.baz:4123/换成Docker容器的内部名称或者IP,比如你那个容器叫test-container,就写成http://test-container:4123/,不然Nginx会去请求外部域名,可能导致循环代理或者无法访问的问题。

备注:内容来源于stack exchange,提问作者Shadark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 11:04:30