Nginx location模塊整理

Nginx環境


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

location模塊

Nginx location

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

location語法

下面是官網的語法結構:正則表達式

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

location @name { ... }服務器

Default:   —app

Context:   server, locationide

官網解釋翻譯和理解

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

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

(翻譯的很差勿噴)翻譯

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/

結果以下:

 

 

從這裏咱們能夠看出當精確匹配和最長匹配相同時,匹配的是精確匹配。

 

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

相關文章
相關標籤/搜索