溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

詳解Nginx靜態(tài)服務(wù)配置(root和alias指令)

發(fā)布時(shí)間:2020-10-04 12:32:10 來(lái)源:腳本之家 閱讀:203 作者:人世間 欄目:服務(wù)器

靜態(tài)文件

Nginx以其高性能著稱,常用與做前端反向代理服務(wù)器。同時(shí)nginx也是一個(gè)高性能的靜態(tài)文件服務(wù)器。通常都會(huì)把應(yīng)用的靜態(tài)文件使用nginx處理。

配置nginx的靜態(tài)文件有兩個(gè)指令,一個(gè) root 和一個(gè) alias。對(duì)于這兩個(gè)指令,是否需要在路徑的后面加上斜杠,經(jīng)常容易讓人犯暈,本文通過(guò)嘗試不同的匹配規(guī)則,歸納了一個(gè)比較通用的配置方式。

基本配置

與Nginx Location Url一文關(guān)于location url配置的實(shí)驗(yàn)一樣,本文也使用vagrant虛擬機(jī)里的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;
}

項(xiàng)目的目錄如下:

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

3 directories, 6 files

分別有兩個(gè)靜態(tài)文件夾,一個(gè)是static,另外一個(gè)是upload。

初識(shí)root

root 是指定項(xiàng)目的根目錄,適用與server和location??梢灾付ǘ鄠€(gè),如果locaiton沒(méi)有指定,會(huì)往其外層的server或http中尋找繼承。

訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58290.jpg 會(huì)發(fā)現(xiàn)圖片已經(jīng)返回。我們還尚未配置 location,為啥會(huì)正確的找到文件?學(xué)習(xí)root或者alias指令的時(shí)候,最好的辦法是給文件拓展名加上一個(gè)字符,使得該文件在硬盤中不存在,那么就能從nginx的error.log中看到nginx尋找文件的方式。

訪問(wèn) https://cache.yisu.com/upload/information/20200622/115/58290.jpgx,然后查看 /var/log/nginx/pro/error.log文件,可以看到如下的錯(cuò)誤信息:

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 文件不存在。的確我們沒(méi)有這個(gè)文件。如果文件名正確,就能訪問(wèn),原因是由于在server中指定了root /vagrant/pro,此時(shí)的nginx就在該目錄下尋找文件,而url上的地址,正好和文件的路徑一致

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

由此可以猜想,nginx中root指令的地址,其實(shí)是替換了匹配后的url中的host。

root指令

為了驗(yàn)證上面的猜想,需要多寫幾個(gè)location做實(shí)驗(yàn)。添加一個(gè)location配置如下:

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

再次訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58290.jpg,發(fā)現(xiàn)并不能顯示圖片了,查看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把地址識(shí)別成/vargrant/pro/static/static/stc.jpg多了一個(gè)static,套用上面的規(guī)則,其組合為192.168.33.10 == /vagrant/pro/static ,url是/static/stc.jpg。置換可以得到/vagrant/pro/static + /static/stc.jpg。與錯(cuò)誤的error一致。解決方案就是把root中的static去掉,馬上就能訪問(wèn)圖片了。

既然是那么把文件夾static命名為stc,其結(jié)果又會(huì)怎樣?

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

訪問(wèn) https://cache.yisu.com/upload/information/20200622/115/58290.jpg 得到錯(cuò)誤:

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"

計(jì)算路徑/vagrant/pro + /static/stc.jpg, 找不到/vagrant/pro/static/stc.jpg文件,符合之前所說(shuō)的規(guī)則,嘗試修改location:

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

因?yàn)閡rl變了,訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58312.jpg,才能夠找到圖片?,F(xiàn)在把stc文件夾變回static。

root 與 斜杠

很多人會(huì)疑惑,路徑最后的斜杠/是否要加呢?location中的static后面的斜杠,和匹配后的url有關(guān),不再贅述。root中的路徑的斜杠/可以再通過(guò)實(shí)驗(yàn)確定。把location配置如下:

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

訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58290.jpg 一切正常,訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58290.jpg,error為找不到"/vagrant/pro/static/stc.jpgs"文件。

如果按照root替換host的規(guī)則,那么替換過(guò)程為

/vagrant/pro/ + /static/stc.jpg == /vagrant/pro//static/stc.jpg。在*nix系統(tǒng)中, 多個(gè)斜杠和一個(gè)斜杠是等價(jià)的,也就是 /vagrant/pro//static/stc.jpg 與/vagrant/pro/static/stc.jpg一樣。

這樣一來(lái),root路徑后面的斜杠,加與不加效果都一樣。既然如此,肯定有人會(huì)想到這么配置:

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

如果安裝之前上面的即算法,那么應(yīng)該是 /vagrant/pro + static/stc.jpg,相加的應(yīng)該是/vagrant/prostatic/stc.jpg,按理說(shuō)應(yīng)該是錯(cuò)誤,可是實(shí)際上卻能訪問(wèn)圖片。咄咄怪事?
如果對(duì)前文nginx location的url匹配規(guī)則了解的話,應(yīng)該看出來(lái)了其實(shí) ^~ static/并不能匹配。修改 location

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

訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58290.jpg依然可以得到圖片,沒(méi)有跳轉(zhuǎn)google,說(shuō)明并沒(méi)有匹配^~ static/。

其實(shí)原理也很簡(jiǎn)單,還記得我們第一次實(shí)驗(yàn),當(dāng)時(shí)尚未配置location,也同樣可以返回圖片。沒(méi)錯(cuò),盡管^~ static/沒(méi)有匹配,而外層的server定義了root為/vagrant/pro,因此搜索圖片正常返回,再注釋外層的root,再一次訪問(wèn)。此時(shí)會(huì)得到一個(gè)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,說(shuō)明即使沒(méi)有指定root,nginx默認(rèn)也有一個(gè)root,/usr/share/nginx/html。當(dāng)然,這個(gè)配置和 ^~ static/沒(méi)有關(guān)系。

如果~ static/stc.jpgs? 那么就能命中,此時(shí)訪問(wèn)圖片,依然能夠正確的解析,因此,并不存在 /vagrant/pro + static/stc.jpg這種情況。理解這里的關(guān)鍵是 root替換host,并加上匹配后的url,匹配后的url當(dāng)然包括前面的斜杠,匹配部分的url則不會(huì)。
對(duì)于 ~ static/stc.jpgs?模式,訪問(wèn)urlhttps://cache.yisu.com/upload/information/20200622/115/58290.jpg

  • 匹配后的url為 /static/stc.jpg
  • 匹配部分的url為  static/stc.jpg

掌握這個(gè)很重要,直接關(guān)系到后面alias指令與斜杠的關(guān)系。

對(duì)于root指令,我們可以歸納。

  1. 對(duì)于匹配后的url地址,將匹配的location中的root路徑替換訪問(wèn)url的host即得到文件的真實(shí)地址。(多個(gè)斜杠其實(shí)等價(jià)于一個(gè)斜杠)
  2. 如果不匹配location,則尋找更外層的root做替換。
  3. root指令最后的斜杠可加可不加。

alias指令

對(duì)于root,操作上很簡(jiǎn)單,只要把root地址替換host后就是文件在硬盤路徑(真實(shí)地址)。對(duì)于alise,它并不是替換匹配后的url地址,而是替換匹配部分的url。alias指令也可以有多個(gè)。
添加一個(gè)location,和root的方式幾乎一樣:

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

訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58321.png并沒(méi)有圖片,查看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"

可見(jiàn) alias的模式并不是/vagrant/pro + /upload/up.png,而是 /vagrant/pro + /up.png。

alias這個(gè)詞在計(jì)算機(jī)里很常用,字面意思是“別名”,顧名思議就是換一個(gè)名字啦。實(shí)際替換規(guī)則就是把匹配的url地址,換成alias中的路徑即可。例如上述的例子替換過(guò)程可以模擬如下:

過(guò)程 模式或url
url模式 ^~ /upload
alias路徑 /vagrant/pro
訪問(wèn)地址 https://cache.yisu.com/upload/information/20200622/115/58321.png
匹配部分的地址 /upload + /up.png
替換 /upload == /vagrant/pro
結(jié)果 /vagrant/pro + /up.png

為了修改圖片的訪問(wèn),修改locaton如下:

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

此時(shí)訪問(wèn)https://cache.yisu.com/upload/information/20200622/115/58321.png就能得到正確的圖片啦,仿造上面的計(jì)算過(guò)程為:

過(guò)程 模式或url
url模式 ^~ /upload
alias路徑 /vagrant/pro/upload
訪問(wèn)地址 https://cache.yisu.com/upload/information/20200622/115/58321.png
匹配部分的地址 /upload + /up.png
替換 /upload == /vagrant/pro/upload
結(jié)果 /vagrant/pro/upload + /up.png

從結(jié)果可以看出,正確的找到了文件路徑,如果alias指令路徑加上斜杠,那么計(jì)算處理的文件路徑為:

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

多個(gè)斜杠是合法的。等價(jià)于一個(gè)斜杠的情況。

下面修改locaiton如下:

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

此時(shí)匹配時(shí)的url則變成  /upload/ + up.jpg, 那么置換的結(jié)果為 /vagrant/pro/upload + up.png,而/vagrant/pro/uploadup.png的路徑是非法的,從error中也能看到置換的錯(cuò)誤:

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"

解決辦法也很簡(jiǎn)單,把/vagrant/pro/upload 改成 /vagrant/pro/upload/即可。由此可見(jiàn),alias最后的斜杠并不像root指令那樣可有可無(wú),是否需要,取決于配合loacation的url匹配模式。

前文root模式中,考慮了沒(méi)有根的斜杠(~ static/stc.jpgs?)這種情況,alias情況下會(huì)很難捕捉錯(cuò)誤。如果locaion配置如下:

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

替換置換的文件路徑應(yīng)該為 /vagrant/pro/upload/up.png,可是實(shí)際測(cè)試中,這樣配置alias,會(huì)一直導(dǎo)致一個(gè)301的重定向,如果alias目錄沒(méi)有打開(kāi)autoindex,則會(huì)拋出一個(gè)403錯(cuò)誤。具體情況尚未知曉,不知道是不是nginx的bug。為了避免這種情況,使用alias的時(shí)候,盡量不要配置location為 ^~ upload/的模式,并且不從根指定url,還是顯得不倫不類。

alise作為別名,比起root的一大好處就是不一定要url上的路徑和文件路徑一樣,因?yàn)閍lise并不是替換host,而是替換匹配部分的host。修改配置如下:

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

訪問(wèn) https://cache.yisu.com/upload/information/20200622/115/58339.jpg或者 https://cache.yisu.com/upload/information/20200622/115/58357.png都能正確的訪問(wèn)到static目錄下的文件,盡管url上是upload。

替換規(guī)則也很簡(jiǎn)單,/upload/ == /vagrant/pro/static/ 得到 /vagrant/pro/static/ + stc.jpg 或 /vagrant/pro/static/ + flask/m.png。

總結(jié)

nginx的靜態(tài)文件配置中,root和alias指令都能實(shí)現(xiàn)。為了避免混淆,盡量不要寫沒(méi)有根路徑的url模式,即避免  static/這樣的開(kāi)頭,根路徑的斜杠需要保留,沒(méi)有根路徑其實(shí)也很奇怪。

root和alias的區(qū)別主要在于替換的部分,root模式中,會(huì)把root配置的路徑替換匹配后的url中的host。alias則把他指定的路徑,替換url中匹配的部分。指令中的斜杠對(duì)于root指令沒(méi)有影響,對(duì)于alise則按照替換規(guī)則匹配即可。

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之后,通常最佳實(shí)際是配置一個(gè)項(xiàng)目的根root,其他的文件夾則使用alias,畢竟alias更加靈活。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI