0%

Nginx location 匹配原則

Nginx location 匹配原則

語法格式

1
2
3
4
5
6
7
8
9
http{
...
server{
location [ = | ~ | ~* | ^~ | @ ] /uri/ {
......
}
}
...
}

location 優先順序比對原則 (重要!!!)

  • “=” > “^“ > ““ > “/uri/“ > “/“ (location 的 前綴)
  • 其中 “=” , “^~” , “@” 和 /uri/ (無任何前綴) 都是屬於 一般 location(也就是文字字串)
  • 其中 ~ , ~* 是屬於 正規表示法的 location
  • location 會先匹配文字字串 ,再匹配正規表示法
  • 文字字串 以匹配最長字串為原則, 文字字串沒有位置的先後順序。
  • 正規表示法 有先後順序

“=”

  • 嚴格精確比對
  • 匹配之後, 即終止後面的location 比對
  • 文字字串比對

“^~”

  • 文字字串比對
  • 匹配之後, 即終止後面的location 比對,其實還有另一種含意 (^ 表示「非」,~ 表示「正規表示法」,字符意思是:不要繼續匹配正規表示法)
  • 區分大小寫
  • 不會做URL encode

“~”

  • 正規表示法比對
  • 區分大小寫

“~*”

  • 正規表示法比對
  • 不區分大小寫

location LAB 實踐演練說明

“^“ ““ 優先順序

  • Nginx 設定檔
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    server {
    listen 80;
    server_name localhost 172.17.0.*;
    root /var/www/html;
    access_log /var/log/nginx/localhost-access.log main;
    error_log /var/log/nginx/localhost-error.log;

    location ~ /test/ {
    echo "A";
    }
    location ^~ /test {
    echo "B";
    }
    }
  • 測試及說明
    1
    2
    3
    curl 172.17.0.2/test/    ==> 會return  B
    按照location 匹配原則;先執行文字字串的比對,再比對正規表示法。
    這邊找到 "^~" 比對文字字串,因 "^~" 特性比對到,就終止後面 正規表示法的比對。

“=” “^“ ““ 優先順序

  • Nginx 設定檔
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    server{
    ...
    location ~ /test/ {
    echo "A";
    }
    location ^~ /test {
    echo "B";
    }
    location =/test{
    echo "C"
    }

  • 測試和說明
    1
    2
    curl 172.17.0.2/test/  ==> return C
    按照location 匹配原則;這邊找到 "=" 比對文字字串,因 "=" 精確比對到,就終止後面 正規表示法的比對。

    “~” 正規表示法 有位置執行順序

  • Nginx 設定檔
    1
    2
    3
    4
    5
    6
    7
    8
    9
    server {
    ....
    location ~ ^/test/.*\.(html|htm|jpg|gif)$ {
    echo "A";
    }
    location ~ ^/test/.*\.(html|htm|jpg|gif|png)$ {
    echo "B";
    }
    }
  • 測試及說明
    1
    2
    3
    4
    5
    6
    7
    8
    curl 172.17.0.2/test/123.html   ==> A
    這邊找不到文字字串比對,再以正規表示法比對, 第一筆location 比對到就終止後面正規表示法的執行。

    curl 172.17.0.2/test/123.jpg ==> A
    這邊找不到文字字串比對,再以正規表示法比對, 第一筆location 比對到就終止後面正規表示法的執行。

    curl 172.17.0.2/test/123.png ==> B
    這邊找不到文字字串比對,再以正規表示法比對, 第一筆location 沒有比對到,再繼續 第二筆正規表示法的比對,比對到就終止後面正規表示法的執行。

    /uri/ ~ 優先順序

  • nginx 設定檔
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    server {
    ....
    location /test/123.png {
    echo "C";
    }

    location ~ ^/test/.*\.(html|htm|jpg|gif)$ {
    echo "Test A";
    }

    location ~ \.(html|png)$ {
    echo "B";
    }

    location ~ ^/test/.*\.(html|htm|jpg|gif|png)$ {
    echo "Test B";
    }
    }
  • 測試及說明
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    curl http://172.17.0.2/test/123.png  ===>  B
    以文字字串比對 匹配到 第一筆location ,再以 正規表示法比對 匹配第三筆 location ,就終止後面的比對。

    若將第三筆 location mark 起來 "#location ~ \.(html|png)$" 測試看看; curl http://172.17.0.2/test/123.png ==> Test B
    以文字字串比對 匹配到 第一筆location ,再以 正規表示法比對 匹配第四筆location,就終止後面的比對。

    將剛才mark 第三筆 location拿掉。測試
    curl http://172.17.0.2/123.html ==> B
    以文字字串比對 沒匹配到,再以 正規表示法比對匹配第三筆 location ,就終止後面的比對。

    curl http://172.17.0.2/test/123.html ==> Test A
    以文字字串比對,沒匹配到,再以正規表示法比對,匹配第二筆 location,就終止後面的比對。

    參考資料:

  • 官網 NGINX- location
  • 51Cto - nginx location 規則優先級
  • Nginx 關於 location 的匹配規則詳解
  • Nginx Location REGEX 比對語法和設定
  • nginx配置location總結及rewrite規則寫法

歡迎關注我的其它發布渠道