Nginx

如何使用 nginx 反向代理正確處理相對 url

  • December 12, 2020

當然,我不是第一個嘗試example.com從 a提供域的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;
   }
}

我可以設法渲染example.cominexample.net/bbb但是的根:

問題 1

example.net/bbb/some/path沒有按預期工作,並且index.htmlofexample.net被渲染。

問題 2

中的任何資產example.com/assets都會給出 404,因為瀏覽器會查找example.net/assets. 如果我可以在不到處放置絕對路徑的情況下解決這個問題,那就太好了。

問題基本上是使用proxy_pass指令不會重寫 HTML 程式碼,因此相對 URL 到例如 aimg 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/; 
  • 如果您可以控制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/; 
  • 放棄使用 example.com 作為 example.net 上的子目錄,而是將其託管在 example.net 的子域上
server { 
 server_name bbb.example.net 
 location / {
    proxy_pass http://example.com/; 
 }
}
  • 通過啟用 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/; 
}

引用自:https://serverfault.com/questions/932628