背景
Nginx location
是使用 nginx 的過程中必須要掌握的技能,無論是在server blocks
還是其他 location blocks
中都會用到,這篇文章簡單介紹了當請求來臨時location
指令是如何處理客戶端URI
請求的.
Nginx 的塊(Block)配置
Nginx 將配置按照層級關係,用塊狀形式進行配置,每當一個請求來臨時,nginx 伺服器就會處理這個請求到底會對映到哪個塊配置.在 Nginx 的配置檔案中,兩種主要的塊配置是:
server
塊配置location
塊配置server
的塊配置包含一系列的虛擬 server 配置,多個 server 配置就可以對多個 domain name 的請求,也包括 ip 埠進行處理. 而location
配置在server
塊配置中起著至關重要的作用,決定了URI
或者資源請求應該如何被處理,這些 URI 請求可以被拆分為多個location
的配置
Nginx Location 指令語法
如下就是常用的 location 配置的語法格式,其中modifier
是可選的,location_match
就是制定 URI 應該去往哪個配置的關鍵.
location optional_modifier location_match {
. . .
}
複製程式碼
Regular expressions(RE)或者字面量都可以用來定義modifier
,如果 location 配置中制定了modifier,可能會改變 nginx匹配 location的方式,如下介紹幾種最重要的modifier:
- (none) 完全沒有modifier表示 location會解釋為字首匹配,要確定匹配項,將根據從URI的開頭匹配該location.
=
等號表示當前這個 location 會匹配一個確定的請求,配置什麼就匹配什麼請求,如果匹配上了,就會停止搜尋.~
波浪號表示當前這個 location 會當成一個大小寫敏感的RE匹配.~*
波浪號跟星號標識 location 會按照大小寫不敏感的 RE 匹配.^~
非表示式(RE)匹配,正規表示式將不會生效.
Ngnix Location的匹配順序
對於每個請求來說,nginx 會選擇最匹配的一個 location 來處理這個請求,nginx 其實就是通過對比這些 location 規則來選擇一個 location,對比的順序可以總結為:
- 首先匹配字首匹配(沒有 RE 表示式),針對當前這個請求,每個字首匹配都匹配一遍.
- 搜尋
=
匹配,如果當前請求匹配上了,搜尋將會停止,直接使用這個這個 location. - 如果第二步沒有匹配上,nginx 會按照如下步驟繼續搜尋最長字首匹配:
3.1 如果最長字首匹配有
^~
這個modifier,nginx 會停止搜尋並直接使用這個 location. 3.2 如果沒有使用^~
,暫存這個 location並且繼續搜尋. - 只要最長字首匹配被暫存和選中,nginx 就會看當前的 location 是否有大小寫敏感的 RE(
~
和~*
),第一個匹配上這種會被當做有效的 location來處理這個請求. - 如果沒有 RE 的 location 匹配上,前面暫存的 location 就會被選中來處理這個請求.
注:所以 沒有修飾符的 location 其實是很浪費資源的,可以用 ^~ 來替代.
舉例
如下是一些 location 配置的例子,用來詳細描述上面所說的處理順序,你也可以按照具體實際情況來修改這些例子.
location = / {
# 只處理請求 /.
}
複製程式碼
location /data/ {
# 所有以 /data/ 匹配,但是還會繼續搜尋.
# 如果沒有其他 location 匹配上,就用這個處理請求.
}
複製程式碼
location ^~ /img/ {
# 所有以 /img/ 開頭的請求並且會停止搜尋.
}
複製程式碼
location ~* .(png|gif|ico|jpg|jpeg)$ {
# 以png, gif, ico, jpg ,jpeg結尾的請求.
# 如果請求是到 /img/ 路徑的話 還是會被上面?的 location 處理
}
複製程式碼
如何防止圖片盜鏈:
location ~ .(png|gif|jpe?g)$ {
valid_referers none blocked yourwebsite.io *.yourwebsite.io;
if ($invalid_referer) {
return 403;
}
}
複製程式碼
在可寫許可權的目錄禁止指令碼:
location ~* /(media|images|cache|tmp|logs)/.*.(php|jsp|pl|py|asp|cgi|sh)$ {
return 403;
}
複製程式碼
更多 nginx location 指令的資訊,可以參見官網:Nginx