語(yǔ)法
location
syntax: location [=|||^~|@] /uri/ { ... }
其中 “~ ” 前綴表示匹配區(qū)分大小寫的正則 location鲸拥,“~ ” 前綴表示匹配不區(qū)分大小寫的正則 location鸠项;其他前綴(包括:“=”茫孔,“^~ ”和“@ ”)和 無(wú)任何前綴的都屬于普通 location吸申,= 精確匹配掌挚,^~ 不使用正則翰苫,@ 內(nèi)部重定向囊嘉。
匹配順序
對(duì)于一個(gè)特定的 HTTP 請(qǐng)求,nginx 應(yīng)該匹配哪個(gè) location 塊的指令呢?
匹配規(guī)則是:先 匹 配 普 通 location 笛求,再 匹 配 正 則 表 達(dá) 式廊移。
對(duì)于匹配普通 location,有如下兩點(diǎn):
匹配 URI 的前綴部分
最大匹配原則
( 因?yàn)?location 不是 “嚴(yán)格匹配”探入,而是 “前綴匹配”画机,就會(huì)產(chǎn)生一個(gè) HTTP 請(qǐng)求,可以 “前綴匹配” 到多個(gè)普通 location新症,例如:location /prefix/mid/ {} 和 location /prefix/ {},對(duì)于請(qǐng)求 /prefix/mid/t.html响禽,前綴匹配的話兩個(gè) location 都滿足徒爹,選哪個(gè)?根據(jù)最大匹配原則 芋类,于是選的是 location /prefix/mid/ {} )
- 對(duì)于正則表達(dá)式的匹配:
通常的規(guī)則是匹配完了 “普通 location” 指令隆嗅,還需要繼續(xù)匹配 “正則 location”。
但是也可以告訴 nginx 匹配到了 “普通 location” 后侯繁,不再需要繼續(xù)匹配 “正則 ” 了胖喳。
要做到這一點(diǎn)只要在 “普通 location” 前面加上 “^~ ” 符號(hào)( ^ 表示 “非”,~ 表示 “正則”贮竟,意思是:不要繼續(xù)匹配正則 )丽焊。
除了 “^~ ” 可以阻止繼續(xù)搜索正則 location 外较剃,還可以加 “=”。
那么 “^~ ” 和 “=” 都能阻止繼續(xù)搜索正則 location 的話技健,那它們之間有什么區(qū)別呢写穴?
區(qū)別很簡(jiǎn)單:
共同點(diǎn)是它們都能阻止繼續(xù)搜索正則 location
不同點(diǎn)是 “^~ ” 依然遵守 “最大前綴” 匹配規(guī)則,然而 “=” 不是 “最大前綴”雌贱,而是嚴(yán)格匹配 ( exact match )
例如啊送,location / {} 和 location = / {} 的區(qū)別:
location / {} 遵守普通 location 的最大前綴匹配。
由于任何 URI 都必然以“/ ”根開頭欣孤,所以對(duì)于一個(gè) URI馋没,如果有更精確的匹配,那自然是選這個(gè)更精確的降传;如果沒(méi)有篷朵,“/ ” 一定能為這個(gè) URI 墊背( 至少能匹配到“/ ”)。
也就是說(shuō) location / {} 有點(diǎn)默認(rèn)配置的味道搬瑰,其他更精確的配置能覆蓋這個(gè)默認(rèn)配置( 這也是為什么我們總能看到 location / {} 這個(gè)配置的一個(gè)很重要的原因)款票。
location = / {}遵守的是 “嚴(yán)格精確匹配 exact match”。
也就是只能匹配對(duì)根目錄的請(qǐng)求泽论,同時(shí)會(huì)禁止繼續(xù)搜索 正則 location艾少。
如果我們只想對(duì) GET / 請(qǐng)求配置作用指令,那么我們可以選 location = / {} 翼悴。這樣能減少正則 location 的搜索缚够,因此效率比 location / {} 高。
普通 location 匹配完后鹦赎,還會(huì)繼續(xù)匹配正則 location谍椅;但是 nginx 允許阻止這種行為,方法很簡(jiǎn)單古话,只需要在普通 location 前加 “^~ ” 或 “=”雏吭。
但其實(shí)還有一種 “隱含” 的方式來(lái)阻止正則 location 的搜索。
這種隱含的方式就是:當(dāng) “最大前綴” 匹配恰好就是一個(gè)“嚴(yán)格精確 ( exact match )”匹配陪踩,照樣會(huì)停止后面的搜索杖们。
原文字面意思是:只要遇到 “精確匹配 exact match”,即使普通 location 沒(méi)有帶 “=” 或 “^~ ” 前綴肩狂,也一樣會(huì)終止后面的匹配摘完。
假設(shè)當(dāng)前配置是:location /exact/match/test.html { 配置指令塊1},location /prefix/ { 配置指令塊2} 和 location ~ .html$ { 配置指令塊3}
如果我們請(qǐng)求 GET /prefix/index.html 傻谁,則會(huì)被匹配到指令塊3 孝治,因?yàn)槠胀?location /prefix/ 依據(jù)最大匹配原則能匹配當(dāng)前請(qǐng)求,但是會(huì)被后面的正則 location 覆蓋;
當(dāng)請(qǐng)求 GET /exact/match/test.html 谈飒,會(huì)匹配到指令塊1 岂座,因?yàn)檫@個(gè)是普通 location 的 exact match ,會(huì)禁止繼續(xù)搜索正則 location步绸。
最后來(lái)看一個(gè)總結(jié)的栗子:
Example:
location = / {
matches the query / only.
[ configuration A ]
}
location / {
matches any query, since all queries begin with /, but regular
expressions and any longer conventional blocks will be
matched first.
[ configuration B ]
}
location ^~ /photos/ {
# matches any query beginning with /images/ and halts searching,
so regular expressions will not be checked.
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
matches any request ending in gif, jpg, or jpeg. However, all
requests to the /images/ directory will be handled by
Configuration C.
[ configuration D ]
}
Example requests:
● / -> configuration A
● /production/document.html -> configuration B
● /photos/1.gif -> configuration C
● /production/1.jpg -> configuration D