Nginx的root和alias兩個(gè)指令之所以讓很多人混淆匈睁,根本原因還是沒(méi)有弄明白這兩個(gè)指令的設(shè)計(jì)用意和適用場(chǎng)景。現(xiàn)在有這么一個(gè)需求:開發(fā)小程序時(shí)桶错,請(qǐng)求的域名騰訊都需要驗(yàn)證,所以開發(fā)經(jīng)常需要放一個(gè)txt驗(yàn)證文件到域名根目錄下面胀蛮,然后騰訊通過(guò)對(duì)這個(gè)文件的訪問(wèn)來(lái)進(jìn)行域名驗(yàn)證院刁。因?yàn)闅v史原因,代碼的根目錄不對(duì)外開放粪狼,這就需要單獨(dú)定義一個(gè)location給txt驗(yàn)證文件使用退腥。那這個(gè)location怎么寫呢,首先看一個(gè)寫法再榄,你覺(jué)得請(qǐng)求 http://test.com/1234.txt Nginx會(huì)乖乖返回200么狡刘?
location /1234.txt {
alias /data/w3/txt/;
}
想好了么?想好了我就公布答案了困鸥,Nginx的accesslog里面會(huì)有兩條記錄嗅蔬,一條301,一條403疾就,意不意外澜术,驚不驚喜?具體原因暫時(shí)不表猬腰,先來(lái)看看alias和root的官方文檔鸟废。
[23/Aug/2018:11:47:28 +0800] "GET /1234.txt HTTP/1.1" 301 284
[23/Aug/2018:11:47:28 +0800] "GET /1234.txt/ HTTP/1.1" 403 596
root和alias的官方定義
- root:Sets the root directory for requests. A path to the file is constructed by merely adding a URI to the value of the root directive. 文檔說(shuō)的很清楚,root就是用來(lái)定義請(qǐng)求的根目錄的姑荷,最終訪問(wèn)的實(shí)際文件的路徑就是root的值+URI盒延,比如下面這種寫法,訪問(wèn) /i/top.gif 的話鼠冕,實(shí)際返回的文件是 /data/w3/i/top.gif添寺。而且文檔還特別強(qiáng)調(diào):如果需要修改URI,請(qǐng)使用alias供鸠。其實(shí)root還是比較容易理解畦贸。
location /i/ {
root /data/w3;
}
- alias:Defines a replacement for the specified location. If alias is used inside a location defined with a regular expression then such regular expression should contain captures and alias should refer to these captures。顧名思義楞捂,alias就是一個(gè)別名薄坏,就是用alias指令所指定的位置的別名。如果alias用在正則定義的location里面的話寨闹,正則里面必須包含捕獲組胶坠,且alias必須使用這些捕獲組。
這里面容易引起混淆的就是這個(gè)別名所代表的具體內(nèi)容繁堡。分兩種情況:
location定義的path是一個(gè)目錄
定義如下沈善,訪問(wèn) /i/top.gif乡数,實(shí)際返回文件是 /data/w3/images/top.gif,注意這里對(duì) /i/ 部分用alias的值進(jìn)行替換了
location /i/ {
alias /data/w3/images/;
}
如果location的path跟alias后部分相同闻牡,則建議使用root净赴,下面兩者等價(jià)。
location /images/ {
alias /data/w3/images/;
}
location /images/ {
root /data/w3;
}
location定義的path是文件
顧名思義罩润,文件的別名肯定還是文件玖翅,所以此時(shí)alias必須配置為文件。如下文
location /i/top.gif {
alias /data/w3/images/top.gif;
}
location ~ ^/users/(.+\.(?:gif|jpe?g|png))$ {
alias /data/w3/images/$1;
}
好了割以,再回到剛開始那個(gè)奇怪的例子金度。仔細(xì)分析需求,這是一個(gè) 不需要修改URI 的需求严沥,適合使用root猜极,寫法很簡(jiǎn)單。如果非要用alias消玄,也能寫出來(lái)跟伏,就是更復(fù)雜一些。
location ~* ^/.+\.txt$ {
root /path/to/nginx/root/path/;
}
location ~* ^/(.+\.txt)$ {
alias /path/to/nginx/root/path/$1;
}
現(xiàn)在再來(lái)看文頭的寫法就不難理解了翩瓜,第一次訪問(wèn)匹配到location酬姆,通過(guò)alias置換之后,對(duì)應(yīng)的返回文件為/data/w3/txt/奥溺,對(duì)Nginx來(lái)說(shuō)辞色,當(dāng)URL指向一個(gè)目錄并且在最后沒(méi)有包含"/"時(shí)烈和,Nginx 內(nèi)部會(huì)自動(dòng)的做一個(gè)301重定向蜂怎,并自動(dòng)添加上"/"叔锐,此時(shí)請(qǐng)求變成http://test.com/1234.txt/金踪,該訪問(wèn)依舊能進(jìn)匹配到該location搭儒,而/data/w3/txt/index.html并不存在蒋困,所以返回403癣籽。順著這個(gè)思路走下去隘竭,請(qǐng)問(wèn)訪問(wèn) http://test.com/1234.txt/1234.txt 會(huì)返回200么方灾?答案顯然是肯定的建蹄。