一文讀懂nginx的location匹配規則


一、location的指令分為兩種匹配模式 :

  • 普通字符串匹配
  • 正則匹配

二、普通匹配包含三種格式:

修飾符 參考示例 說明
location /hello/world 前綴匹配,不支持正則
= location = /hello/world 又叫精確匹配,不支持正則,匹配后既終止正則匹配又終止普通匹配
^~ location ^~ /hello/world 前綴匹配,不支持正則 ,匹配后不再進行正則匹配

三、正則匹配包含兩種格式:

修飾符 參考示例 說明
~ location ~ \.jpg$ 區分大小寫的正則匹配,是包含匹配,而非前綴匹配
~* location ~* \.jpg$ 不區分大小寫的正則匹配,是包含匹配,而非前綴匹配

四、location匹配順序

五、關於location匹配的一些誤區

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

矯正: location 的匹配順序其實是“先匹配普通,再“考慮”匹配正則”。注意這里的“考慮”是“可能”的意思,也就是說匹配完“普通 location ”后,有的時候需要繼續匹配“正則 location ”,有的時候則不需要繼續匹配“正則 location ”。兩種情況下,不需要繼續匹配正則 location :
( 1 )當普通 location 前面指定了“ ^~ ”,特別告訴 Nginx 本條普通 location 一旦匹配上,則不需要繼續正則匹配;
( 2 )當普通location 恰好嚴格匹配上,不是最大前綴匹配,則不再繼續匹配正則。

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

矯正:這句話不全對,“普通 location ”的匹配規則是“最大前綴”,因此“普通 location ”的確與 location 編輯順序無關;但是“正則 location ”的匹配規則是“順序匹配,且只要匹配到第一個就停止后面的匹配”

總結一句話:“正則 location 匹配讓步普通 location 的嚴格精確匹配結果;但覆蓋普通 location 的最大前綴匹配結果”

六、舉個栗子

此處我用的是openresty版本的nginx,因此可以直接使用echo指令。如果是原生nginx,要使用echo指令的話,則需要自行編譯安裝echo-nginx-module,參考:https://github.com/openresty/echo-nginx-module#installation

    server {
        listen       80;
        server_name  localhost;
        location / {
            echo "first";
        }

        location ^~ /hello {
            echo "111111-normal";
        }

        location /hello/world {
            echo "222222-normal";
        }

        location ~ /hello/world {
            echo "333333-regex";
        }
    }

訪問http://127.0.0.1/hello/world的結果如下:

分析
在這個例子中,先進行普通匹配,按照最長匹配的原則,匹配到第三個location,然后這里的修飾符是非"="或"^~",則會繼續向下進行正則匹配,匹配到第四個location。

我們對上面的栗子進行稍加修改,將第三個和第四個location調換下順序,且將location /hello/world 修改為location ^~ /hello/world 如下:

    server {
        listen       80;
        server_name  localhost;
        location / {
            echo "first";
        }

        location ^~ /hello {
            echo "111111-normal";
        }

        location ~ /hello/world {
            echo "333333-regex";
        }

        location ^~ /hello/world {
            echo "222222-normal";
        }

    }

這時候再訪問http://127.0.0.1/hello/world的結果如下:

由此可以說明,匹配的順序是“先普通,再“考慮”正則”,而"="或"^~"這兩個修飾符會終止“考慮”正則。看到這里,是不是就清晰了很多呢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM