通過location划分來反向代理多個網站,意思是使用同一個域下(協議、域名、端口均相同),通過路徑的划分來代理不同的網站/服務。例如:a網站為 www.test.com/a/,b網站為www.test.com/b/,c網站為www.test.com/c/,這樣的好處是只需要使用一個域名,abc三個網站之間不存在跨域問題,但壞處也很明顯:
- 三個網站的cookie、webStorage都未隔離,如果沒做好規划存在沖突的可能
- 有些代碼中使用了絕對路徑,那么在使用絕對路徑時,跳轉時用於區分網站的前綴"/a/”就會丟失
為了解決問題2,這里有幾個方法,但並不是很完美:
- 使用ngx_http_sub_module模塊對輸出的內容進行過濾:
這個模塊並不是nginx默認的模塊,但是nginx提供的官方docker鏡像的最新版本中是有自帶的,可以通過nginx -V來查看是否有安裝
location /a/ {
proxy_pass http://10.119.2.1/; #這里加斜杠意味着URI,nginx會把前綴 a/ 替換掉
······
#通過直接替換的方式把輸出內容中的URL替換掉
sub_filter '="/luci-static/' '="/a/luci-static/';
sub_filter ':"/luci-static/' ':"/a/luci-static/';
sub_filter_types *;
sub_filter_once off;
proxy_redirect / /a/; #替換重定向的URL
}
- 很多情況下並不是所有的路徑都可以被直接直接替換掉,有些路徑是前端代碼動態生成的,這種情況很難被完全替換
通過請求header中的Refer去區分,例如:從www.test.com/a/1.html請求www.test.com/2.html,這個請求的Refer是www.test.com/a/1.html,但繼續從www.test.com/2.html請求別的地址,Refer中就不再包含/a/了,所以這種方式只能兜底判斷一層
location / {
proxy_set_header Host $host;
#這里通過正則表達式去匹配refer的內容
if ($http_referer ~ ^https?://[\w\.:]*/a.*) {
# 將其路由到127.0.0.1的一個路徑前綴為/a/的地址
rewrite ^(/.*)$ /a$1 break;
proxy_pass http://127.0.0.1;
}
}
- 剩下依然無法被匹配的地址,可以手動通過正則或者前綴的方式增加location來完成匹配