前言,我這里驗(yàn)證的nginx-v1.23.2單機(jī)環(huán)境下的nginx中的正則表達(dá)式、location路徑匹配規(guī)則和優(yōu)先級。
先準(zhǔn)備好環(huán)境,基礎(chǔ)配置是這樣 nginx/conf/conf.d/host.conf :
server { listen 8081; server_name 10.90.5.70; proxy_connect_timeout 60; proxy_read_timeout 600; proxy_send_timeout 600; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto "http"; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_next_upstream error non_idempotent; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; location / { root /usr/share/nginx/html; index index.html index.htm; } }
下面的案例都是基于以上配置驗(yàn)證的。
一,nginx中的正則表達(dá)式
nginx中的正則表達(dá)式基本遵循了Regular Expression格式和規(guī)則。不同的是,一般以特殊字符代表正則表達(dá)式的開始,即標(biāo)識要用Regular Expression處理其后的字符。
nginx里面可以使用正則表達(dá)式的部分可以是 server里,或者location 路徑上。
常見的正則表達(dá)式的含義
^ :匹配輸入字符串的起始位置 $ :匹配輸入字符串的結(jié)束位置 . :匹配除“ ”之外的任何單個字符,若要匹配包括“ ”在內(nèi)的任意字符,請使用諸如“[. ]”之類的模式 d :匹配純數(shù)字 w :匹配字母或數(shù)字或下劃線或漢字 s :匹配任意的空白符 :匹配單詞的開始或結(jié)束 【下面這部分是標(biāo)注匹配長度(字符數(shù)量、重復(fù)數(shù)量)的】 * :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll” + :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o” ? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}” {n} :重復(fù) n 次 {n,} :重復(fù) n 次或更多次 {n,m} :重復(fù) n 到 m 次 [] :定義匹配的字符范圍 [c] :匹配單個字符 c 注意:在括號里面用-表示范圍: [a-z] :匹配 a-z 小寫字母的任意一個 [a-zA-Z0-9] :匹配所有大小寫字母或數(shù)字 () :表達(dá)式的開始和結(jié)束位置 例如:(jpg|gif|swf|) | :或運(yùn)算符 ! :非運(yùn)算符(與其后面的表達(dá)式去反運(yùn)算) 正則表達(dá)式里面沒有“與運(yùn)算符”。 :轉(zhuǎn)義字符,將后面接著的字符標(biāo)記為一個特殊字符或一個原義字符或一個向后引用。如“ ”匹配一個換行符,而“$”則匹配“$”
參考鏈接:https://www.jb51.net/article/149053.htm
二,location路徑匹配規(guī)則和優(yōu)先級
location:用來設(shè)置請求的URI。nginx中l(wèi)ocation配置項(xiàng)是最基礎(chǔ)的配置,而且它的配置也稍顯復(fù)雜。
location匹配規(guī)則 與 優(yōu)先級
默認(rèn)值 /
語法location [ = | ~ | ~* | ^~ ] uri { ... }
位置 server,location
uri變量是待匹配的請求字符串,可以不包含正則表達(dá)式,也可以包含正則表達(dá)式。那么:
nginx服務(wù)器在搜索匹配location的時候,是先使用不包含正則表達(dá)式進(jìn)行匹配,找到一個匹配度最高的一個,然后在通過包含正則表達(dá)式的進(jìn)行匹配,如果能匹配到直接訪問,匹配不到,就使用剛才匹配度最高的那個location來處理請求。
另一種描述,意思是一樣的:
location 匹配的優(yōu)先級(與location在配置文件中的順序無關(guān)) = 精確匹配會第一個被處理。如果發(fā)現(xiàn)精確匹配,nginx停止搜索其他匹配。 普通字符匹配,正則表達(dá)式規(guī)則和長的塊規(guī)則將被優(yōu)先和查詢匹配,也就是說如果該項(xiàng)匹配還需去看有沒有正則表達(dá)式匹配和更長的匹配。 ^~ 則只匹配該規(guī)則,nginx停止搜索其他匹配,否則nginx會繼續(xù)處理其他location指令。 最后匹配理帶有"~"和"~*"的指令,如果找到相應(yīng)的匹配,則nginx停止搜索其他匹配; 當(dāng)沒有正則表達(dá)式或者沒有正則表達(dá)式被匹配的情況下,那么匹配程度最高的逐字匹配指令會被使用。
location 優(yōu)先級官方文檔:
1. Directives with the = prefix that match the query exactly. If found, searching stops. 2. All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops. 3. Regular expressions, in order of definition in the configuration file. 4. If #3 yielded a match, that result is used. Else the match from #2 is used. 1. =前綴的指令嚴(yán)格匹配這個查詢。如果找到,停止搜索。 2. 所有剩下的常規(guī)字符串,最長的匹配。如果這個匹配使用^?前綴,搜索停止。 3. 正則表達(dá)式,在配置文件中定義的順序。 4. 如果第3條規(guī)則產(chǎn)生匹配的話,結(jié)果被使用。否則,如同從第2條規(guī)則被使用。
它包含了路徑的匹配規(guī)則和針對該規(guī)則的配置。
location規(guī)則按照前導(dǎo)符主要分五類:
代號 | 前導(dǎo)符 | 說明 |
---|---|---|
① | = uri | 全字匹配,只有當(dāng)請求路徑和uri完全匹配時,對應(yīng)的規(guī)則才會生效 |
② | ~ regular | 區(qū)分大小寫的正則匹配 |
③ | ~* regular | 不區(qū)分大小寫的正則匹配 |
④ | ^~ uri | 否定正則的路徑匹配 |
⑤ | url | 沒有任何前導(dǎo)符的路徑匹配 |
這五類規(guī)則,同時存在配置文件中時,按照一定的優(yōu)先級規(guī)則生效。
優(yōu)先級:( location = ) > ( location 完整路徑 ) > ( location ^~ 否定正則 ) > ( location ~* 正則順序 ) > ( location ~ 區(qū)分大小寫正則順序 ) > ( location 部分起始路徑 ) > ( / )
優(yōu)先級:① > ④ > ③ > ② > ⑤
nginx規(guī)則決定流程如下圖:
文字說明:
以下說明非常關(guān)鍵
一、檢查請求uri是否與某個=規(guī)則匹配,如果有,直接應(yīng)用規(guī)則,終止后續(xù)匹配。
二、nginx首先檢查所有路徑匹配規(guī)則配置項(xiàng),包括"^~"規(guī)則和沒有前導(dǎo)符號的規(guī)則,選擇并記住和當(dāng)前請求uri匹配度最長的配置項(xiàng)。但這個時候,并不會啟用相關(guān)的配置,而僅僅是記住。
三、判斷上一步中選擇下來的路徑規(guī)則是否包含 ^~ ,如果包含,則使用該條規(guī)則,終止后續(xù)匹配。
四、按配置順序進(jìn)行正則表達(dá)式檢查,匹配到第一條合適的正則表達(dá)式時,使用該條規(guī)則,終止后續(xù)匹配。
五、使用步驟三選擇出來的路徑匹配規(guī)則。
下面以實(shí)例屬性介紹:
1,不帶符號,要求必須以指定模式開始
location指令實(shí)例:
server { listen 8081; server_name 127.0.0.1; # 不帶符號,要求必須以指定模式開始(區(qū)分大小寫,并且后面帶/是有區(qū)別的) location /aaa { default_type text/plain; return 200 "access success aaa "; } } # 能匹配到: http://127.0.0.1:8081/aaa http://127.0.0.1:8081/aaa/ http://127.0.0.1:8081/aaadef http://127.0.0.1:8081/aaa/def/ http://127.0.0.1:8081/aaa?p1=TOM # 不能匹配到(大小寫區(qū)分): http://127.0.0.1:8081/Aaa # 如果規(guī)則(后面跟/目錄符號) location /aaa/ { 則只能匹配到下面兩行: http://127.0.0.1:8081/aaa/ http://127.0.0.1:8081/aaa/def/
如圖:
2,= 用于不包含正則表達(dá)式的uri前,必須與指定的模式精確匹配
實(shí)測,等于號后面有或沒有空格不影響效果。location指令實(shí)例:
server { listen 8081; server_name 127.0.0.1; # = : 用于不包含正則表達(dá)式的uri前,必須與指定的模式精確匹配(區(qū)分大小寫,并且后面帶/是有區(qū)別的) location = /bbb { default_type text/plain; return 200 "access success bbb "; } } # 能匹配到: http://127.0.0.1:8081/bbb http://127.0.0.1:8081/bbb?p1=TOM # 不能匹配到(大小寫區(qū)分): http://127.0.0.1:8081/bbb/ http://127.0.0.1:8081/bbbcd http://127.0.0.1:8081/Bbb
如圖:
3,包含正則表達(dá)式的
~ :用于表示當(dāng)前uri中包含了正則表達(dá)式,并且區(qū)分大小寫
~*: 用于表示當(dāng)前uri中包含了正則表達(dá)式,并且不區(qū)分大小寫
換句話說,如果uri包含了正則表達(dá)式,需要用上述兩個符合來標(biāo)識
^~: 用于不包含正則表達(dá)式的uri前,功能和不加符號的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了。(可用它提升優(yōu)先級)
含正則表達(dá)式的location指令,實(shí)例一:
server { listen 8081; server_name 127.0.0.1; # ~ :用于表示當(dāng)前uri中包含了正則表達(dá)式,并且區(qū)分大小寫 # 正則表達(dá)式:區(qū)分大小寫,以/abc開頭,以1個字母或數(shù)字或下劃線或漢字結(jié)束的 location ~^/eeew$ { default_type text/plain; return 200 "access success. 000 Regular expression matched: eee "; } } # 能匹配到: http://127.0.0.1:8081/eeeb http://127.0.0.1:8081/eeeB http://127.0.0.1:8081/eee2 # 不能匹配到(大小寫區(qū)分): http://127.0.0.1:8081/eee http://127.0.0.1:8081/Eee http://127.0.0.1:8081/eee/ http://127.0.0.1:8081/eeedef http://127.0.0.1:8081/eee/def/ http://127.0.0.1:8081/eee?p1=TOM
如圖:
含正則表達(dá)式的location指令,實(shí)例二:
server { listen 8081; server_name 127.0.0.1; # ~*: 用于表示當(dāng)前uri中包含了正則表達(dá)式,并且不區(qū)分大小寫 # 正則表達(dá)式:不區(qū)分大小寫,以/abc開頭,以字母或數(shù)字或下劃線或漢字結(jié)束的 location ~*^/dddw$ { default_type text/plain; return 200 "access success. 111 Regular expression matched: ddd "; } } # 能匹配到: http://127.0.0.1:8081/dddb http://127.0.0.1:8081/dddB http://127.0.0.1:8081/ddd2 http://127.0.0.1:8081/DddH # 不能匹配到(大小寫區(qū)分): http://127.0.0.1:8081/ddd http://127.0.0.1:8081/Ddd http://127.0.0.1:8081/ddd/ http://127.0.0.1:8081/ddddef http://127.0.0.1:8081/ddd/def/ http://127.0.0.1:8081/ddd?p1=TOM
如圖:
不包含正則表達(dá)式的location指令,實(shí)例三:
server { listen 8081; server_name 127.0.0.1; # ^~: 用于不包含正則表達(dá)式的uri前,功能和不加符號的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了,可用于提升優(yōu)先級。(區(qū)分大小寫,并且后面帶/是有區(qū)別的) location ^~ /fff { default_type text/plain; return 200 "access success. Non Regular expression matched: fff "; } } # 能匹配到: http://127.0.0.1:8081/fff http://127.0.0.1:8081/fff/ http://127.0.0.1:8081/fffdef http://127.0.0.1:8081/fff/def/ http://127.0.0.1:8081/fff?p1=TOM # 不能匹配到(大小寫區(qū)分): http://127.0.0.1:8081/Fff http://127.0.0.1:8081/pp/fff # 如果規(guī)則(后面跟/目錄符號) location /fff/ { 則只能匹配到下面兩行: http://127.0.0.1:8081/fff/ http://127.0.0.1:8081/fff/def/
如圖:
定義一個命名的 location
用"@" 定義一個命名的 location,使用在內(nèi)部定向時,例如:error_page, try_files
@location 例子:
# 示例:404錯誤頁將被內(nèi)部重定向 error_page 404 = @fetch; location @fetch( proxy_pass http://fetch; ) # 類似案例: error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; }
鏈接:https://www.cnblogs.com/xiongzaiqiren/p/16968651.html
-
字符串
+關(guān)注
關(guān)注
1文章
577瀏覽量
20485 -
nginx
+關(guān)注
關(guān)注
0文章
143瀏覽量
12163 -
正則表達(dá)式
+關(guān)注
關(guān)注
0文章
26瀏覽量
3477
原文標(biāo)題:nginx中的正則表達(dá)式和location路徑匹配指南
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論