Nginx location模塊整理

Nginx環境


 轉載於:http://www.cnblogs.com/zhaof/p/5945576.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

location模塊

Nginx location

location 指令的作用是根據用戶請求的URI來執行不同的應用,URI就是根據用戶請求到的網址URL進行匹配,匹配成功了進行相關的操作。

location語法

下面是官網的語法結構:

Syntax:    location [ = | ~ | ~* | ^~ ] uri { ... }

location @name { ... }

Default:   —

Context:   server, location

官網解釋翻譯和理解

下面會結合官網原文進行解釋,以下英文部分均從官網摘抄:

http://nginx.org/en/docs/http/ngx_http_core_module.html#location

(翻譯的不好勿噴)

Sets configuration depending on a request URI.

根據請求的URI進行配置

URI 變量是待匹配的請求字符串,

A location can either be defined by a prefix string, or by a regular expression.

Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching)

一個location可以用prefix string(前綴字符串)定義,也可以通過regular expression(正則表達式來定義)

通俗的說也就是:我們可以通過使用不同的前綴,表達不同的含義,對於不同的前綴可以分爲兩大類:普通location和正則location

符號:”~”表示uri包含正則,並且區分大小寫

符號:“~*”表示uri包含正則,但不區分大小寫

注意:如果你的uri用正則,則你的正則前面必須添加~或者~*,之前我在這裏存在誤區,以爲可以不加~或者~*

To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

Nginx服務器會首先會檢查多個location中是否有普通的uri匹配,如果有多個匹配,會先記住匹配度最高的那個。然後再檢查正則匹配,這裏切記正則匹配是有順序的,從上到下依次匹配,一旦匹配成功,則結束檢查,並就會使用這個location塊處理此請求。如果正則匹配全部失敗,就會使用剛纔記錄普通uri匹配度最高的那個location塊處理此請求。

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

當普通匹配的最長前綴匹配有符號“^~”的時候,就不會在匹配正則

直接使用當前匹配的這個location塊處理此請求

Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.

使用符號“=”修飾符可以定義一個精確匹配的URI和位置,如果找到了一個精確的匹配,則搜索終止,例如,如果一個”/”請求頻繁發生,定義“location =/”將加快這些請求的處理,一旦精確匹配只有就結束,這樣的location顯然不能包含嵌套location

這裏我們說一下location / {} 和location =/ {}的區別:

“location / {}”是普通的最大前綴匹配,任何的uri肯定是以“/”開頭,所以location / {} 可以說是默認匹配,當其他都不匹配了,則匹配默認匹配

根據上述官網內容進行總結

a. ”=”用於普通uri前,要求精確匹配,如果匹配成功,則停止搜索並用當前location處理此請求

b. ”~” 表示uri包含正則,並且區分大小寫

c. “~*”表示uri包含正則,但不區分大小寫

d. ”^~”表示在普通uri前要求Nginx服務器找到普通uri匹配度最高的那個location後,立即處理此請求,並不再進行正則匹配

e. ”^~”和“=”都可以阻止繼續匹配正則location兩者的區別:“^~”依然遵守最大前綴原則,然後“=”是需要嚴格匹配

關於location網上的一些誤解

location 的匹配順序是“先匹配正則,再匹配普通”

這是一個錯誤的結論,從上面官網的文章中我們可以知道:

先匹配普通uri,然後記住匹配度最高的那個(官網原話:To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered.)然後匹配正則,如果正則匹配則結束查找,如果正則不匹配,則匹配之前普通匹配中匹配度最高的那個將執行該請求(官網原話:Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.)

所以:location 的匹配順序是“先匹配正則,再匹配普通” 這句話肯定是錯誤的,況且這裏並沒有包含”^~”和“=”

location 的執行邏輯跟 location 的編輯順序無關。

這也是一種錯誤的理解,我們根據上述內容可以知道:

如果是普通uri 匹配,這個時候是沒有順序的,但是正則匹配則是有順序的,是從上到下依次匹配,一旦有匹配成功,則停止後面的匹配

 

那麼順序到底是怎麼匹配呢?

我畫了一個location匹配的邏輯圖便於理解匹配的順序規則

 

 

通過實驗來驗證出結果

對www.conf配置如下:

[root@nginx extra]# cat www.conf

    server {

        listen       80;

        server_name  www.zhaofan.com;

        access_log      logs/access_www.log;

        root    html/www;

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

 

        location  /documents/ {

            return 403;

        }

        location  ^~ /p_w_picpaths/ {

            return 404;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

    }

[root@nginx extra]#

注意:

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

這個部分$前面不能有空格,否則會提示如下錯誤:

[root@nginx extra]# ../../sbin/nginx -s reload

nginx: [emerg] invalid location modifier "~*\.(gif|jpg|jpeg)" in /application/nginx1.6.2/conf/extra/www.conf:19

如果$後面沒有空格,則會提示如下錯誤:

[root@nginx extra]# ../../sbin/nginx -s reload

nginx: [emerg] directive "location" has no opening "{" in /application/nginx1.6.2/conf/extra/www.conf:23

這些都是細節問題,一定要注意

實驗一:登錄nginx網站,我這裏的直接打開:http://192.168.8.105/

 

 

可以看出這裏是精確匹配

        location = / {

            return 402;

        }

 

實驗二:打開http://192.168.8.105/aaa/

 

 

這裏可以看出因爲都不匹配,所以最後匹配了location / {}

        location / {

            return 401;

        }

 

實驗三:打開http://192.168.8.105/1.gif

 

 

這裏可以看出是匹配了正則

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

 

實驗四:打開http://192.168.8.105/aaa/1.gif

 

 

這裏依然是匹配正則

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

 

實驗五:打開http://192.168.8.105/p_w_picpaths/1.gif

 

 

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

 

        location  /document/ {

            return 403;

        }

        location  ^~ /p_w_picpaths/ {

            return 404;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

這裏通過配置把實驗三和實驗四的對比就可以看出來因爲普通匹配裏有“^~”,並且匹配到了p_w_picpaths,所以這個就是不進行正則匹配

        location  ^~ /p_w_picpaths/ {

            return 404;

        }

實驗六:“^~”遵守最大前綴原則

配置如下:

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

 

        location  = /document/ {

            return 403;

        }

        location  ^~ /p_w_picpaths/ {

            return 404;

        }

        location   /p_w_picpaths/1/ {

            return 501;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

還是關注標紅的地方,這個時候我們登陸:http://192.168.1.19/p_w_picpaths/

結果如下:

 

 

從這裏可以看出匹配了:

        location  ^~ /p_w_picpaths/ {

            return 404;

        }

但是如果我們登陸:http://192.168.1.19/p_w_picpaths/1/

結果如下;

 

 

這裏匹配了:

        location   /p_w_picpaths/1/ {

            return 501;

        }

從這裏我們可以看出“^~”遵守最大匹配原則。

實驗七:當最長匹配和精確匹配相同時

配置如下:

        location / {

            return 401;

        }

        location = / {

            return 402;

        }

 

        location  = /document/ {

            return 403;

        }

        location  ^~ /p_w_picpaths/ {

            return 404;

        }

        location   /p_w_picpaths/1/ {

            return 501;

        }

 

        location  =  /p_w_picpaths/1/ {

            return 502;

        }

        location ~* \.(gif|jpg|jpeg)$ {

            return 500;

        }

登陸:http://192.168.1.19/p_w_picpaths/1/

結果如下:

 

 

但是如果這個時候登陸:http://192.168.1.19/p_w_picpaths/1/aaa/

結果如下:

 

 

從這裏我們可以看出當精確匹配和最長匹配相同時,匹配的是精確匹配。

 

不在過多的做實驗,根據上面的邏輯圖應該可以解決碰到的問題了


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章