nginx location配置規則學習

最近學習vuejs,作先後端分離,demo作完了,最終仍是要發佈的,因而學習nginx,其它配置卻是還好理解,惟獨對localtion理解不了,最後請教了一些網友,才得以解決問題,可是不但願下次還遇到問題,因此這裏把localtion的配置規則,都嘗試一遍,也記錄一下,方便本身,也方便別人。html

一、配置規則

只要在網上搜一下,或者去官網翻一下文檔,都能知道有幾種規則,這是官網的:vue

Syntax:    location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default:    —
Context:    server, location

總而言之,包含兩部份內容,一部分是匹配前提條件或者叫要求,另一部分是要匹配的東西,也就是匹配內容。nginx

下面這段是官網說明的谷歌翻譯:正則表達式

在對「%XX」形式編碼的文本進行解碼以後,針對歸一化的URI執行匹配,解析對相對路徑組件「.」和「..」的引用,以及將兩個或多個相鄰斜槓可能壓縮爲單個斜槓。

localtion能夠由前綴字符串或正則表達式定義。正則表達式使用前面的「〜*」修飾符(不區分大小寫匹配)或「〜」修飾符(用於區分大小寫匹配)指定。要找到匹配給定請求的位置,nginx首先檢查使用前綴字符串(前綴位置)定義的位置。其中,選擇並記住具備最長匹配前綴的位置。而後檢查正則表達式,按照它們在配置文件中的顯示順序。正則表達式的搜索在第一個匹配中終止,而且使用相應的配置。若是沒有找到與正則表達式匹配,則使用以前記住的前綴位置的配置。

localtion blocks能夠嵌套,下面提到一些例外。

對於不區分大小寫的操做系統,如macOS和Cygwin,與前綴字符串的匹配忽略了一個狀況(0.7.7)。可是,比較僅限於一個字節的區域設置。

正則表達式能夠包含稍後能夠在其餘指令中使用的捕獲(0.7.40)。

若是最長匹配的前綴位置具備「^〜」修飾符,則不會檢查正則表達式。

另外,使用「=」修飾符能夠定義一個徹底匹配的URI和位置。若是找到徹底匹配,則搜索終止。例如,若是頻繁出現「/」請求,則定義「location = /」將加快對這些請求的處理,由於搜索在第一次比較以後當即終止。這樣的位置不能明顯地包含嵌套的位置。

在從0.7.1到0.8.41的版本中,若是請求匹配前綴位置而沒有「=」和「^〜」修飾符,則搜索也將被終止,而正則表達式未被檢查

根據上面的說明可知,默認狀況, nginx先檢查前綴字符串,而後檢查正則表達式,若是前綴字符串匹配到了,而且前綴字符串有這個「^~」 要求,就不配正則了;若是沒有這個「^~」 ,即便前綴匹配到了,也要去匹配正則表則,若是正則表達式匹配到了,就是用正則表達式的,沒有就是用前綴字符串匹配到的路徑;後端

二、無正則表達式匹配

規則:使用匹配到的最長的前綴的路徑。前後端分離

location  / {
            root   html;
            index  index.html index.htm;
        }
        
        location  /img {
            root   D:/nginx/img;
            index  test.png;
        }

這是nginx下載安裝完成後,增長了一個叫img的配置,訪問路徑是http://localhost/img,訪問一下看看什麼效果,我開啓了日誌,就不截圖了,直接看日誌裏,nginx查找的路徑:學習

D:/nginx/img/img/test.png" is not found (3: The system cannot find the path specified)

文件查找的路徑是D:/nginx/img(這是我配置的路徑),下面的img文件下的test.png文件測試

若是改爲這樣:ui

location  / {
            root   html;
            index  index.html index.htm;
        }
        
        location  /img/ {
            root   D:/nginx/img;
            index  test.png;
        }

看看有沒有區別,從新啓動,在訪問http://localhost/img試一下:編碼

"D:/nginx/img/img/test.png" is not found (3: The system cannot find the path specified)

和以前沒什麼區別,也就是兩個效果是同樣的,在瀏覽其中http://localhost/imghttp://localhost/img/是同樣的。

再改一下,重啓:

location  / {
                root   html;
                index  index.html index.htm;
            }
            
            location  /img/ {
                root   D:/nginx/img/;
                index  test.png;
            }

我在從新訪問一下:

"D:/nginx/img/img/test.png" is not found (3: The system cannot find the path specified)

仍是同樣的效果。
因此若是是前綴字符串匹配,就不要糾結後面要不要加「/」的問題。
另外從結果上看,確實符合規則,使用前綴最長的匹配路徑。

二、有正則匹配,無符號修飾

規則:無「^~」, 最終使用正則匹配到的路徑,正則匹配不到,使用字符串前綴匹配最長的

增長一個配置:

location  \/img\/ {
                root   D:/nginx/reg/;
                index  test.png;
            }

重啓訪問:

"D:/nginx/img/img/test.png" is not found (3: The system cannot find the path specified)

結果發現,找的仍是D:/nginx/img的img文件夾的文件,好像正則沒有匹配上,改一下:

location  \/img {
                root   D:/nginx/reg/;
                index  test.png;
            }

這下必定能夠匹配上了,重啓http://localhost/img測試:

"D:/nginx/img/img/test.png" is not found (3: The system cannot find the path specified)

無語了,爲何沒有按照規則來呢,爲何沒有查找D:/nginx/reg/路徑下的文件呢?

回到前面看一下官網說明,發現正則表達式須要"~"或者"~*"指定才行,修改成下面的配置:

location ~* \/img\/ {
                root   D:/nginx/reg/;
                index  test.png;
            }

重啓訪問http://localhost/img測試:

"D:/nginx/reg/img/test.png"

這下按照規則了,看東西看來仍是要認真看啊!

改一下正則表達式:

location ~* \/img {
                root   D:/nginx/reg/;
                index  test.png;
            }

再重啓測試:

"D:/nginx/reg/img/test.png" is not found (3: The system cannot find the path specified)

也能夠正常匹配,也就是說正則匹配的狀況下,最後一個/要不要都行,效果是同樣的

另外「~*」 不區分大小寫和「~」就不用試,應該都知道

三、精確匹配=號

規則:精確匹配某個路徑,優先級最高

增長一種配置:

location = /img/test.png {
                root   D:/nginx/denghao/;
                index  test.png;
            }

重啓訪問路徑http://localhost/img/test.png

"D:/nginx/denghao/img/test.png" failed (3: The system cannot find the path specified)

從結果看出,和規則一致;

改一下配置:

location = /img/ {
                    root   D:/nginx/wuhouzhui/;
                    index  test.png;
                }

測試結果:

"D:/nginx/reg/img/test.png" is not found (3: The system cannot find the path specified)

從結果上看,最終使用的匹配路徑是正則,至於 = /img/,有沒有匹配到,我也不清楚,總而言之,這種狀況下使用的是正則的路徑,有知道朋友解釋一下=號有沒有匹配到。

四、提升前綴字符串的優先級的「^~」

規則:若是最長匹配的前綴位置具備「^〜」修飾符,則不會檢查正則表達式

由於先搜索匹配的是前綴字符串,全部匹配到了,有這個修飾符就不檢查正則了,因此正則就不考慮了。
把配置改一下:

location ^~ /img/ {
                root   D:/nginx/img/;
                index  test.png;
            }
            
            location = /img/test.png {
                root   D:/nginx/denghao/;
                index  test.png;
            }

訪問http://localhost/img/test.png測試:

"D:/nginx/denghao/img/test.png" failed (3: The system cannot find the path specified)

能夠看到匹配結果是等號的路徑,因此=號的優先級比^~高

五、總結

搜索優先級:

精確匹配 > 字符串匹配( 長 > 短 [ 注: ^~ 匹配則中止匹配 ]) > 正則匹配( 上 > 下 )

使用優先級:

精確匹配 > (^~) > 正則匹配( 上 > 下 )>字符串(長 > 端)

剛學的,若是有錯誤,請指出,我修改,別讓錯誤誤導他人。

相關文章
相關標籤/搜索