如何使用 nginx 反向代理正确处理相对 url

a.b*_*eri 22 nginx reverse-proxy proxypass

当然,我不是第一个尝试从 为域提供服务example.com的人example.net/bbb,但我还没有找到解决方案。

我的 NGINX 配置遵循指导方针,看起来像这样:

server {
    listen 80;
    server_name example.net;
    root /path/to/aaa;

    location /bbb/ {
        proxy_pass http://example.com/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
    location ~ \.(svg|ttf|js|css|svgz|eot|otf|woff|jpg|jpeg|gif|png|ico)$ {
        access_log off;
        log_not_found off;
        expires max;
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以设法渲染example.comin的根,example.net/bbb但是:

问题 1

example.net/bbb/some/path预期和不工作index.htmlexample.net呈现。

问题 2

中的任何资产example.com/assets都会给出 404,因为浏览器会查找example.net/assets. 如果我能在不到处放置绝对路径的情况下解决这个问题,那就太好了。

HBr*_*ijn 41

问题基本上是使用proxy_pass指令不会重写 HTML 代码,因此相对 URLimg src="/assets/image.png"不会神奇地更改为img src="/bbb/assets/image.png".

我在这里写了在 Apache httpd 中解决这个问题的潜在策略,nginx 也可以使用类似的解决方案:

  • 如果您可以控制example.com应用程序/内容在那里的部署方式和部署方式,请部署在您要在 example.net 上用于反向代理的相同基本 URI
    --> 部署您的代码 example.com/bbb,然后您proxy_pass将变得非常简单/assets/image.png 将被移动到 /bbb/assets/image.png:

    location /bbb/ {
         proxy_pass http://example.com/bbb/; 
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果你有控制example.com和应用/内容是如何部署:
    更改为相对路径,即而不是img src="/assets/image.png"
    img src="./assets/image.png"从页example.com/index.html
    ,并img src="../../assets/image.png"从页example.com/some/path/index.html

  • 也许你很幸运,example.com 只在根目录中使用了几个 URI 路径,example.net 不使用这些路径,然后只需反向代理每个必要的子目录

    location /bbb/ {
         proxy_pass http://example.com/; 
    }
    location /assets/ {
         proxy_pass http://example.com/assets/; 
    }
    location /styles/ {
         proxy_pass http://example.com/styles/; 
    
    Run Code Online (Sandbox Code Playgroud)
  • 放弃使用 example.com 作为 example.net 上的子目录,而是将其托管在 example.net 的子域上

    server { 
      server_name bbb.example.net 
      location / {
         proxy_pass http://example.com/; 
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 通过启用 nginx ngx_http_sub_module重写(HTML)内容。这也将允许您使用类似于以下内容的内容重写绝对 URL:

    location /bbb/ {
         sub_filter 'src="/assets/'  'src="/bbb/assets/';
         sub_filter 'src="http://example.com/js/' 'src="http://www.example.net/bbb/js/' ;
         sub_filter_once off;
         proxy_pass http://example.com/; 
    }
    
    Run Code Online (Sandbox Code Playgroud)