Nginx靜態服務配置---詳解root和alias指令

Nginx靜態服務配置---詳解root和alias指令

96

靜態文件

Nginx以其高性能著稱,經常使用與作前端反向代理服務器。同時nginx也是一個高性能的靜態文件服務器。一般都會把應用的靜態文件使用nginx處理。html

配置nginx的靜態文件有兩個指令,一個 root 和一個 alias。對於這兩個指令,是否須要在路徑的後面加上斜槓,常常容易讓人犯暈,本文經過嘗試不一樣的匹配規則,概括了一個比較通用的配置方式。前端

基本配置

簡明 Nginx Location Url 配置筆記一文關於location url配置的實驗同樣,本文也使用vagrant虛擬機裏的nginx。其基本配置以下:nginx

/etc/nginx/sites-enabled/pro.conf算法

server {
        listen 80 default_server;


        server_name localhost;

        access_log /var/log/nginx/pro/access.log;
        error_log /var/log/nginx/pro/error.log;

        error_page 404 /404.html;

        root /vagrant/pro;
        index index.html index.htm;

}

項目的目錄以下:flask

☁  pro  tree
.
├── 403.html
├── 404.html
├── index.html
├── static
│   ├── flask
│   │   └── m.png
│   └── stc.jpg
└── upload
    └── up.png

3 directories, 6 files

分別有兩個靜態文件夾,一個是static,另一個是upload。服務器

初識root

root 是指定項目的根目錄,適用與server和location。能夠指定多個,若是locaiton沒有指定,會往其外層的server或http中尋找繼承。性能

訪問http://192.168.33.10/static/stc.jpg 會發現圖片已經返回。咱們還還沒有配置 location,爲啥會正確的找到文件?學習root或者alias指令的時候,最好的辦法是給文件拓展名加上一個字符,使得該文件在硬盤中不存在,那麼就能從nginxerror.log中看到nginx尋找文件的方式。學習

訪問 http://192.168.33.10/static/stc.jpgx,而後查看 /var/log/nginx/pro/error.log文件,能夠看到以下的錯誤信息:測試

2016/09/28 07:41:48 [error] 4416#0: *70 open() "/vagrant/pro/static/stc.jpgx" failed (2: No such file or directory), client: 192.168.33.1, server: localhost, request: "GET /static/stc.jpgx HTTP/1.1", host: "192.168.33.10"

/vagrant/pro/static/stc.jpgx 文件不存在。的確咱們沒有這個文件。若是文件名正確,就能訪問,緣由是因爲在server中指定了root /vagrant/pro,此時的nginx就在該目錄下尋找文件,而url上的地址,正好和文件的路徑一致google

http://192.168.33.10  /static/stc.jpg 
 /vagrant/pro          /static/stc.jpg

由此能夠猜測,nginx中root指令的地址,實際上是替換了匹配後的url中的host。

root指令

爲了驗證上面的猜測,須要多寫幾個location作實驗。添加一個location配置以下:

location ^~ /static {
    root /vagrant/pro/static;
}

再次訪問http://192.168.33.10/static/stc.jpg,發現並不能顯示圖片了,查看error.log 返回以下:

2016/09/28 07:48:57 [error] 5978#0: *71 open() "/vagrant/pro/static/static/stc.jpg" failed (2: No such file or directory), client: 192.168.33.1, server: localhost, request: "GET /static/stc.jpg HTTP/1.1", host: "192.168.33.10"

nginx把地址識別成/vargrant/pro/static/static/stc.jpg多了一個static,套用上面的規則,其組合爲192.168.33.10 == /vagrant/pro/static ,url是/static/stc.jpg。置換能夠獲得/vagrant/pro/static + /static/stc.jpg。與錯誤的error一致。解決方案就是把root中的static去掉,立刻就能訪問圖片了。

既然是那麼把文件夾static命名爲stc,其結果又會怎樣?

location ^~ /static {
    root /vagrant/pro;
}

訪問 http://192.168.33.10/static/stc.jpg 獲得錯誤:

2016/09/28 07:54:46 [error] 5992#0: *73 open() "/vagrant/pro/static/stc.jpg" failed (2: No such file or directory), client: 192.168.33.1, server: localhost, request: "GET /static/stc.jpg HTTP/1.1", host: "192.168.33.10"

計算路徑/vagrant/pro + /static/stc.jpg, 找不到/vagrant/pro/static/stc.jpg文件,符合以前所說的規則,嘗試修改location:

location ^~ /stc {
    root /vagrant/pro;
}

由於url變了,訪問http://192.168.33.10/stc/stc.jpg,纔可以找到圖片。如今把stc文件夾變回static。

root 與 斜槓

不少人會疑惑,路徑最後的斜槓/是否要加呢?location中的static後面的斜槓,和匹配後的url有關,再也不贅述。root中的路徑的斜槓/能夠再經過實驗肯定。把location配置以下:

location ^~ /static/ {
   root /vagrant/pro/;
}

訪問http://192.168.33.10/static/stc.jpg 一切正常,訪問http://192.168.33.10/static/stc.jpg,error爲找不到"/vagrant/pro/static/stc.jpgs"文件。

若是按照root替換host的規則,那麼替換過程爲

/vagrant/pro/ + /static/stc.jpg == /vagrant/pro//static/stc.jpg。在*nix系統中, 多個斜槓和一個斜槓是等價的,也就是 /vagrant/pro//static/stc.jpg/vagrant/pro/static/stc.jpg同樣。

這樣一來,root路徑後面的斜槓,加與不加效果都同樣。既然如此,確定有人會想到這麼配置:

location ^~ static/ {
    root /vagrant/pro;
}

若是安裝以前上面的即算法,那麼應該是 /vagrant/pro + static/stc.jpg,相加的應該是/vagrant/prostatic/stc.jpg,按理說應該是錯誤,但是實際上卻能訪問圖片。咄咄怪事?

若是對前文nginx location的url匹配規則瞭解的話,應該看出來了其實 ^~ static/並不能匹配。修改 location

location ^~ static/ {
    rewrite ^ http://google.com;
   # root /vagrant/pro;
}

訪問http://192.168.33.10/static/stc.jpg依然能夠獲得圖片,沒有跳轉google,說明並無匹配^~ static/

其實原理也很簡單,還記得咱們第一次實驗,當時還沒有配置location,也一樣能夠返回圖片。沒錯,儘管^~ static/沒有匹配,而外層的server定義了root爲/vagrant/pro,所以搜索圖片正常返回,再註釋外層的root,再一次訪問。此時會獲得一個404,查看error以下:

2016/09/28 08:18:15 [error] 6227#0: *82 open() "/usr/share/nginx/html/static/stc.jpg" failed (2: No such file or directory), client: 192.168.33.1, server: localhost, request: "GET /static/stc.jpg HTTP/1.1", host: "192.168.33.10"

/usr/share/nginx/html/static/stc.jpg,說明即便沒有指定root,nginx默認也有一個root,/usr/share/nginx/html。固然,這個配置和 ^~ static/沒有關係。

若是~ static/stc.jpgs? 那麼就能命中,此時訪問圖片,依然可以正確的解析,所以,並不存在 /vagrant/pro + static/stc.jpg這種狀況。理解這裏的關鍵是 root替換host,並加上匹配後的url,匹配後的url固然包括前面的斜槓,匹配部分的url則不會。

對於 ~ static/stc.jpgs?模式,訪問urlhttp://192.168.33.10/static/stc.jpg

  • 匹配後的url爲 /static/stc.jpg
  • 匹配部分的url爲 static/stc.jpg

掌握這個很重要,直接關係到後面alias指令與斜槓的關係。

對於root指令,咱們能夠概括。

  1. 對於匹配後的url地址,將匹配的location中的root路徑替換訪問url的host即獲得文件的真實地址。(多個斜槓其實等價於一個斜槓)
  2. 若是不匹配location,則尋找更外層的root作替換。
  3. root指令最後的斜槓可加可不加。

alias指令

對於root,操做上很簡單,只要把root地址替換host後就是文件在硬盤路徑(真實地址)。對於alise,它並非替換匹配後的url地址,而是替換匹配部分的url。alias指令也能夠有多個。

添加一個location,和root的方式幾乎同樣:

location ^~ /upload {
   alias /vagrant/pro;
}

訪問http://192.168.33.10/upload/up.png並無圖片,查看error獲得:

2016/09/28 08:36:18 [error] 6312#0: *90 open() "/vagrant/pro/up.png" failed (2: No such file or directory), client: 192.168.33.1, server: localhost, request: "GET /upload/up.png HTTP/1.1", host: "192.168.33.10"

可見 alias的模式並非/vagrant/pro + /upload/up.png,而是 /vagrant/pro + /up.png

alias這個詞在計算機裏很經常使用,字面意思是「別名」,顧名思議就是換一個名字啦。實際替換規則就是把匹配的url地址,換成alias中的路徑便可。例如上述的例子替換過程能夠模擬以下:

過程 模式或url
url模式 ^~ /upload
alias路徑 /vagrant/pro
訪問地址 http://192.168.33.10/upload/up.png
匹配部分的地址 /upload + /up.png
替換 /upload == /vagrant/pro
結果 /vagrant/pro + /up.png

爲了修改圖片的訪問,修改locaton以下:

location ^~ /upload {
    alias /vagrant/pro/upload;
}

此時訪問http://192.168.33.10/upload/up.png就能獲得正確的圖片啦,仿造上面的計算過程爲:

過程 模式或url
url模式 ^~ /upload
alias路徑 /vagrant/pro/upload
訪問地址 http://192.168.33.10/upload/up.png
匹配部分的地址 /upload + /up.png
替換 /upload == /vagrant/pro/upload
結果 /vagrant/pro/upload + /up.png

從結果能夠看出,正確的找到了文件路徑,若是alias指令路徑加上斜槓,那麼計算處理的文件路徑爲:

/upload == /vagrant/pro/upload
/vagrant/pro/upload/ + /up.png

多個斜槓是合法的。等價於一個斜槓的狀況。

下面修改locaiton以下:

location ^~ /upload/ {
   alias /vagrant/pro/upload;
}

此時匹配時的url則變成 /upload/ + up.jpg, 那麼置換的結果爲 /vagrant/pro/upload + up.png,而/vagrant/pro/uploadup.png的路徑是非法的,從error中也能看到置換的錯誤:

2016/09/28 08:52:44 [error] 6452#0: *92 open() "/vagrant/pro/uploadup.png" failed (2: No such file or directory), client: 192.168.33.1, server: localhost, request: "GET /upload/up.png HTTP/1.1", host: "192.168.33.10"

解決辦法也很簡單,把/vagrant/pro/upload 改爲 /vagrant/pro/upload/便可。因而可知,alias最後的斜槓並不像root指令那樣無關緊要,是否須要,取決於配合loacation的url匹配模式。

前文root模式中,考慮了沒有根的斜槓(~ static/stc.jpgs?)這種狀況,alias狀況下會很難捕捉錯誤。若是locaion配置以下:

location ^~ upload/ {
      alias /vagrant/pro/upload/;
}

替換置換的文件路徑應該爲 /vagrant/pro/upload/up.png,但是實際測試中,這樣配置alias,會一直致使一個301的重定向,若是alias目錄沒有打開autoindex,則會拋出一個403錯誤。具體狀況還沒有知曉,不知道是否是nginx的bug。爲了不這種狀況,使用alias的時候,儘可能不要配置location爲 ^~ upload/的模式,而且不從根指定url,仍是顯得不三不四。

alise做爲別名,比起root的一大好處就是不必定要url上的路徑和文件路徑同樣,由於alise並非替換host,而是替換匹配部分的host。修改配置以下:

location ^~ /upload/ {
    alias /vagrant/pro/static/;
}

訪問 http://192.168.33.10/upload/stc.jpg或者 http://192.168.33.10/upload/flask/m.png都能正確的訪問到static目錄下的文件,儘管url上是upload。

替換規則也很簡單,/upload/ == /vagrant/pro/static/ 獲得 /vagrant/pro/static/ + stc.jpg/vagrant/pro/static/ + flask/m.png

總結

nginx的靜態文件配置中,root和alias指令都能實現。爲了不混淆,儘可能不要寫沒有根路徑的url模式,即避免 static/這樣的開頭,根路徑斜槓須要保留,沒有根路徑其實也很奇怪。

root和alias的區別主要在於替換的部分,root模式中,會把root配置的路徑替換匹配後的url中的host。alias則把他指定的路徑,替換url中匹配的部分。指令中的斜槓對於root指令沒有影響,對於alise則按照替換規則匹配便可。

root 指令

location /dir/ 
root root_path ->  http://host/dir/file.txt  -> root_path/dir/file.txt

alias 指令

location /dir
alias alias_path ->  http://host /dir /file.txt  -> alias_path/file.txt

location /dir/ 
alias alias_path/ ->  http://host /dir/ file.txt  -> alias_path/file.txt

瞭解了root和alise以後,一般最佳實際是配置一個項目的根root,其餘的文件夾則使用alias,畢竟alias更加靈活

相關文章
相關標籤/搜索