本文非徹底原創, 更多的是將相關資料進行整理html
Last-Modified: 2019年5月10日15:28:29linux
語法 | 匹配規則 |
---|---|
空 | 普通匹配(遵循最大前綴匹配規則, 優先度比正則低) |
= | 精確(嚴格)匹配, 優先度最高 後續再也不匹配正則 |
^~ | 非正則匹配(依然遵循最大前綴匹配規則) 後續再也不匹配正則 |
~ | 表示區分大小寫的正則匹配 |
~* | 表示不區分大小寫的正則匹配 |
/ | 通用匹配,任何請求都會匹配到(本質上等同於語法 空 ) |
!~
和 !~*
分別爲區分大小寫不匹配及不區分大小寫不匹配 的正則, 可是是用於條件判斷的時候(即 if
語句)nginx
if ($host !~* "^www\.") { # ... }
匹配簡單來講:正則表達式
=
精確匹配, 若未匹配到則轉下一步驟空
, ^~
)若最終匹配到 ^~
, 則使用瀏覽器
若匹配到 空
或 未匹配到, 則轉下一步驟(當前匹配結果暫時保存)測試
若未匹配到任意正則, 則使用步驟2中匹配到普通正則url
只有兩類:正則location和普通locationspa
~
和 ~*
爲正則location=
、^~
、@
和無任何前綴的都屬於普通location,另外,@
是用做服務端內部的一種轉發行爲,不多用,在此不作討論。.net
location /a/{}
,location /a/b/ {}
,請求 http://a/b/c.html 匹配的是 location /a/b/ {}
=
或 非正則匹配 ^~
, 則再也不進行後續的正則匹配普通location與正則location之間的匹配結果選擇code
會繼續正則location的匹配,
綜上,常規的順序是匹配完普通location,還要繼續匹配正則location,可是,也能夠告訴nginx,匹配到了普通location,就不要再搜索匹配正則location了,經過在普通location前面加上^~
符號,^
表示非,~
表示正則,^~
就是表示不要繼續匹配正則。
除了^~
,=
也可阻止nginx繼續匹配正則,區別在於^~
依然遵循最大前綴匹配規則,而=是嚴格匹配
location / {}
和 location =/ {}
的區別/ {}
做爲普通匹配,是遵循最大前綴匹配原則的,因此,對於一個url,若是有更特殊合適的匹配,就選特殊合適的,若是沒有更特殊合適的匹配,也有 / {}
兜着,就像是默認配置同樣
=/ {}
遵循的是嚴格匹配規則,只能匹配到 http://ip:port/,同時會中止搜索正則匹配。
接下來測試驗證。
1.先驗證第二條:普通location之間的匹配順序:按最大前綴匹配
nginx.conf配置:
#普通location location /a/b { return 666; } #普通location location /a/b/c { return 777; }
測試連接:http://192.168.88.38/a/b,http狀態碼爲666,符合預期。如圖(後面的測試可自行F12打開瀏覽器控制檯查看http狀態碼,再也不截圖):
測試連接:http://192.168.88.38/a/b/c,http狀態碼爲777,匹配的是location /a/b/c {return 777;},符合預期。
2.驗證第三條:正則location之間的匹配順序:按配置文件中的物理順序匹配,只要匹配到一條正則,就再也不考慮後面的
nginx.conf配置:
location ~* /a { return 999; } #匹配a-z的任意一個字母 location ~* ^/[a-z]$ { return 666; }
測試連接:http://192.168.88.38/a,http狀態碼999,匹配的是location ~* /a {renturn 999;},符合預期。
將nginx.conf中的兩個正則匹配順序調換下:
location ~* ^/[a-z]$ { return 666; } location ~* /a { return 999; }
測試連接:http://192.168.88.38/a,http狀態碼666,匹配的是location ~* ^/[a-z]$,符合預期。
3.驗證第4條,其實第4條就至關因而總結性的匹配順序了:
nginx.conf配置:
#普通location location /a { return 666; } #普通location location /a/b { return 777; } #正則location location ~* /a/b { return 888; }
測試連接:http://192.168.88.38/a,http狀態碼666,匹配到普通location,location /a {return 666;},符合預期。
測試連接:http://192.168.88.38/a/b,http狀態碼777,先進行普通location匹配,遵循最大前綴原則,匹配到location /a/b {return 777; },可是,這只是一個臨時結果,由於接下來還要繼續往下進行正則location匹配,匹配到 location ~* /a/b { return 888; },最終返回結果爲888。符合預期。
將正則location的規則改下:
#普通location location /a { return 666; } #普通location location /a/b { return 777; } #正則location location ~* /a/c { return 888; }
測試連接:http://192.168.88.38/a/b,http狀態碼777,匹配到location /a/b {return 777; },而且由於接下來沒有符合的正則location,因此最終返回爲777,符合預期。
綜上,location的匹配順序及結果取值都符合2,3,4點結論。
接下來再測試驗證普通location中的^~及=符號對於匹配搜索過程的阻斷效果,固然,別忘了這倆符號的真實做用。^~爲普通字符匹配,=爲精確匹配。
^~測試驗證nginx.conf配置:
location /a { return 666; } #普通匹配 location ^~ /a/b { return 777; } #正則location location ~* /a/b { return 888; }
測試連接:http://192.168.88.38/a/b,匹配到 location ^~ /a/b {return 777;}後,由於使用了^~符號,再也不繼續搜索正則location匹配,因此,雖然下面有符合條件的正則location,可是最終仍是返回了777,符合預期。
=測試驗證nginx.conf配置:
location /a { return 666; } #普通匹配 location = /a/b { return 777; } #正則location location ~* /a/b { return 888; }
測試連接:http://192.168.88.38/a/b,匹配到 location = /a/b {return 777;}後,由於使用了=符號,再也不繼續搜索正則location匹配,最終返回777,符合預期。
另附上經常使用正則表達式: