介紹nginx中location塊的匹配符(~, ~*, ^~, [space]等)與alias檔案代理的關係
實驗環境
靜態資源目錄
E: /static
- a.js
- b.js
-
/case/
- c.js
- d.js
- e.js
nginx server塊
server {
listen 80;
server_name 127.0.0.1;
}
alias代理特定檔案
僅僅代理一個特定的檔案,基本上很少會出錯,
location塊是字首匹配和正則匹配均可。
如下,瀏覽器訪問http://127.0.0.1/static/case/… 都返回c.js的內容。
location /static/case/c.js {
alias E:/static/case/c.js;
}
location ~ /static/case/c.js {
alias E:/static/case/c.js;
}
alias代理某目錄下的各個檔案
但當需要代理一個目錄下的各個檔案時,會因location塊是字首匹配和正則匹配的不同,導致代理的結果不同。
尤其是location是正則匹配時,較為特殊,容易出錯。
location是字首匹配^~或者[space]時
這種情況如果出錯,一般就是由於對location URI部分和alias部分最後加不加“/”犯糊塗導致的,
或者說是不清楚這種情況下最終代理到什麼path導致的。
// case1
location /static/case/ {
alias E:/static/case/;
autoindex on;
}
// case2
location /static/case {
alias E:/static/case/;
autoindex on;
}
case3
location /static/case/ {
alias E:/static/case;
autoindex on;
}
case4
location /static/case {
alias E:/static/case;
autoindex on;
}
以上四種情況,瀏覽器輸入:http://127.0.0.1/static/case/… 只有第三種失敗。
如果在這四種情況的location前面都加上 ^~ 結果也是一樣的,因為 ^~ 和[space]都是字首匹配。
**最終代理路徑是: alias路徑 + location部分URI和瀏覽器輸入的URL未匹配到的部分。
這個路徑下有檔案,就200,沒有檔案,就404。**
所以分析一下為什麼第三種寫法不能正確代理呢,
瀏覽器URL: http://127.0.0.1/static/case/…,
location:/static/case/,
因此兩個URL匹配部分是/static/case/,
未匹配部分是c.js。
因此它最終代理的path是:E:/static/case + c.js = E:/static/casec.js,相當於找static目錄下有沒有casec.js檔案,因為沒這個檔案,所以404。
location是正則匹配~, ~*時
location ~ /static/case/ {
alias E:/static/case/;
autoindex on;
}
瀏覽器URL1:http://127.0.0.1/static/case/…
瀏覽器URL2:http://127.0.0.1/static/case/…
瀏覽器URL3:http://127.0.0.1/static/case/…
瀏覽器URL4:http://127.0.0.1/static/case/,
結果都是一樣的,返回/static/case目錄。
其中只有URL4,直接200返回。URL1-3都是301->200。
重定向不是無限的,當瀏覽器URL case後的層級大於10時,就不再301->200,而是直接200返回。
即,瀏覽器URL5,直接200返回。代理到/static/case目錄。
瀏覽器URL5:http://127.0.0.1/static/case/…
因此,代理目錄時,location還是正則匹配的話,是無法訪問到這個目錄下的各個檔案的。
解決辦法有兩個。
關於既想用~又想能代理到某目錄下各個檔案的解決辦法:
//方案1
location ~ ^/(.+)/(.+)/(.+.js)$ {
alias E:/static/case/$3;
}
//方案2、用root結合rewrite代替
location ~ ^/.+/.+/.+.js$ {
root E:/;
rewrite ^/(.*) /$1 break;
}