nginx訪問靜態資源的相關配置
引言
需要通過nginx服務讀取靜態文件,需要配置nginx.conf的相關配置,如虛擬主機配置server、location配置。
其實nginx.conf的配置文件是由指令集組成的,指令集分為:簡單指令、模塊指令。
簡單的指令由名字和參數組成,中間用空格隔開,末尾用分號(;)結尾。
模塊指令和簡單指令有着相同的結構,但是末尾的分號(;)改為了花括號({})
如果模塊指令中含有其它的模塊指令,那么該模塊指令就叫做上下文(context),比如http模塊指令、server模塊指令。
1、server模塊指令
server模塊指令是nginx用來配置虛擬主機的
什么是虛擬主機?

server模塊指令中有三個重要的指令:listen 監聽端口號,server_name 服務名,location映射解析文件地址

2、location模塊指令
向server模塊指令添加location模塊指令如下:
location / {
root 文件地址
}
如下:

解釋這段指令:
location中指定的“/html”會和請求的uri做比較,如果符合,那么uri會加載到root指令集中指定的路徑“E:\javaWork\XXXX\0521”后面。
舉個例子說明:如果在瀏覽器的地址欄寫上/html/23/24/xx.html的話,那么因為uri里含有html,那么就能夠匹配到這個location指定的“/html"。
所以完整的映射文件解析地址是:E:\javaWork\XXXX\0521\html\23\24\xx.html
前半部分加下划線的就是root指令集指定的路徑,后半部分是匹配得到的uri。
(1)一個目錄可以對應多個location指令集
這樣的話,一個文件的目錄可以寫成多個location指令進行匹配,因為最后訪問的話是根據root指令集所指的地址 加上 location指定的uri拼接的
就拿上面E:\javaWork\XXXX\0521\html\23\24這個目錄通過root指令對應的的地址和location指定的uri拼接能夠得到的方式有:(舉幾種,不舉全)
(1)root E:\javaWork\XXXX\0521; location \html\23\24;
(2)root E:\javaWork\XXXX\0521\html; location \23\24;
(3)root E:\javaWork\XXXX\0521\html\23; location \24;
如果server指令集寫的端口是8084,server_name是localhost。
那么上面的三種root指令集對應的地址和location對應的uri拼接情況,可以通過以下三種方式取到 \24 目錄下對應的靜態文件。
(1)localhost:8084/html/23/24/xx.html (匹配第一個對應的location指令集)
(2)localhost:8084/23/24/xx.html (匹配第二個對應的location指令集)
(3)localhost:8084/24/xx.html (匹配第三個對應的location指令集)
(2)優先更全的uri匹配原則(精確匹配原則)
如果兩個不同的目錄有以下兩個location指令對應
(1)
location /0521 {
root E:/java/jvm;
}
(2)
location /0521/doc {
root D:/java/gc;
}
這時,如果在瀏覽器地址欄訪問localhost:8084/0521/doc/hello.html
(1)假設E:/java/jvm/0521目錄下有doc文件夾,並且里面有hello.html靜態文件。
(2)假設D:/java/gc/0521/doc目錄下,有hello.html靜態文件。
這一步是不是給弄懵逼了?請求的uri符合這兩個location指令的匹配,那么具體匹配哪一個呢?
那就是按照精確匹配原則,哪個location對應的uri更加和請求的uri精確,那么就匹配哪個location指令集。也就是說,在上面那個問題中,會匹配第二個location指令集。
證明上面結論:
(1)創建測試文件
D盤符文件,及hello.html內容:

E盤符文件,及hello.html內容:

(2)給nginx.conf增加兩個location指令集

(3)重新加載nginx.conf配置文件
使用 nginx -s reload 命令重新加載nginx.conf配置文件
(4)瀏覽器地址欄訪問:localhost:8084/0521/doc/hello.html
對吧?匹配的就是指向D盤的那個location。 如果所匹配的location並不是你所期望的那樣或者諸如此類的其它問題,那么你可以去查看logs目錄下的error.log和access.log這兩個日志文件。

(3)一個請求始終只匹配最精確的location
到這里,再拋出一個問題,接着上面的操作,精確匹配確實是匹配到了指向D盤的location,那么,如果我要匹配的文件在doc目錄下,並沒有呢?nginx會對瀏覽器發出的請求如何處理,是直接拋出404嗎?
我們可以嘗試着將第二個location對應的目錄下的hello.html進行刪除,再去訪問localhost:8084/0521/doc/hello.html;看看是否會訪問E盤下的hello.html
結果顯然,並不會去匹配第一個映射E盤的location,也就是說,如果uri已經匹配到當前這個精確location的話,那么如果沒有需要訪問的文件,那么直接拋出404,而不會去繼續匹配其它的不精確的location。
(4)額外注意
這段話是個人總結的,網上沒見着相關結論。
location的映射文件地址是root對應地址加上location的uri。(E:\javaWork\XXXX\0521\html\23\24)
如果要訪問這個地址 (E:\javaWork\XXXX\0521\html\23\24) 的前一層或前幾層目錄下的文件,那么只能通過匹配另外的location。並不能通過相對路徑(..)的形式訪問到。
我們讓一個文件地址匹配兩個location指令,如下圖:
(1)匹配的第一個location,這個location的文件映射地址是:E:\javaWork\XXX\0521\html
(2)匹配的第二個location,這個location的文件映射地址是:E:\javaWork\XXX\0521\html\static\html\self_test
我們可以看見頁面報錯了,是由於頁面用到的jquery沒有正確引入。
這是為什么?因為磁盤上沒有嗎?可是第一個location映射文件地址是可以的,所以顯然 並不是 這個原因。
這是因為nginx通過這個location,只讀取了E:\javaWork\XXX\0521\html\static\html\self_test目錄下的文件進來。而jquery文件,並不在這個目錄下。
也就是說,nginx只會讀取location映射的文件地址下的所有文件,除此目錄外的文件一律獲取不到。