NGINX 反向代理未加载资源

NGINX 反向代理未加载资源

我正在尝试在一些内部 Web 服务前面放置一个反向代理。

Nginx 已设置并正常工作以处理请求。如果我location /在 conf 文件中只提供一个,它会成功加载该 proxy_pass 目标,即:

location / {
  proxy_pass https://internal.ip:port/;
 }

浏览至https://public_proxy_address/完美加载内部资源。

但是,由于我有多个内部应用程序,我想通过 nginx 代理所有应用程序。因此,在测试中,我将配置更改为如下:

location /app1 {
  proxy_pass https://internal.ip:port/;
}

完成这些后,我得到了主/默认内部应用程序索引页,但查看源代码显示没有链接样式表、js 或其他资源正在被重写。因此,页面的所有内容都无法加载。在 Apache 中,我可能会编写一个proxyhtmlurlmap ^/resource/ /app1/resource R。但我找不到在 nginx 中实现此目的的任何方法。

我也尝试过这个,但没有成功:

location /app1 {
  rewrite /resource(.*?) /app1/resource$1 break;
  proxy_pass https://internal.ip:port/;
 }

如何让 nginx 正确地将目标位置(app1)添加到请求的资源 URL 前面,以便它们加载?

答案1

由于我没有足够的信用,我无法对条目发表评论,因此,我的回应作为单独的条目出现。

我不知道原帖作者为什么不同意,但我认为 Martin Fjordval 正确地指出了问题并提出了正确的建议。不过我建议对他的代码片段进行如下修改;

                location /app1/ {
                    proxy_set_header Host $http_host/app1;
                    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;
                    proxy_redirect    off;
                    add_header Pragma "no-cache";
                    add_header Cache-Control "no-cache";

                    proxy_pass http://internal.ip:port/;
                    sub_filter 'action="/'  'action="/app1/';
                    sub_filter 'href="/'  'href="/app1/';
                    sub_filter 'src="/'  'src="/app1/';
                    sub_filter_once off;
            }

因此,如果您确定所有以“/”开头的相对 URL 都需要重定向,则上述代码会将“/app1/”附加到所有 URL 上,并在引用时让“location /app1/”块捕获它们。然后,您可以查看页面源代码并确认重写正在进行。

您可能还需要整个或至少部分“proxy_set_header”shabang,尤其是“proxy_set_header Host $http_host/app1”位。

答案2

我最终选择了基于子域名的代理。基本原理如下:

server {
   listen 443 ssl;
   ssl on;
   ssl_cert <cert>;
   ssl_key <key>;

   server_name appname1.public.com;

   location / {
     proxy_pass https://internalapp1.ip:port
    }
}

server {
   listen 443 ssl;
   ssl on;
   ssl_cert <cert>;
   ssl_key <key>;

   server_name appname2.public.com;

   location / {
     proxy_pass https://internalapp2.ip:port
    }
}

这样就无需进行任何直接的 URL 或资源重写。

答案3

如果我正确理解了您的问题,那么问题似乎是您的应用程序认为它托管在根 uri 上,/而实际上它托管在/app1,只是没有被告知这一点。Nginx 通常不会修改后端的响应,这是您所期望的,但是,这是可能的。

首先,您需要检查应用中是否有可以定义根 uri 的配置选项。如果有,那么设置是迄今为止最简单的解决方案。

如果你找不到任何东西,你可以使用替代模块替换 HTML 中的 URL。请注意,要使此功能正常工作,您需要在后端禁用 GZIP 编码,以便 nginx 可以看到未压缩的 HTML。

子过滤器的示例

location /app1 {
    sub_filter '<a href="/resource/' '<a href="/app1/resource/';
    sub_filter_once off;

    proxy_pass https://internal.ip:port/;
}

答案4

我遇到了同样的问题;索引页正在加载,但所有资源都收到 404。

我注意到在我所在的位置:try_files $uri $uri/ =404; 这会为所有资源返回 404。只需将其删除即可。

location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        # try_files $uri $uri/ =404;                       <---- Comment out this line.
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

相关内容