Nginx Location 指令語法解析

candyleer發表於2019-02-23

nginx location

本文翻譯自 www.keycdn.com/support/ngi…

背景

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,對比的順序可以總結為:

  1. 首先匹配字首匹配(沒有 RE 表示式),針對當前這個請求,每個字首匹配都匹配一遍.
  2. 搜尋=匹配,如果當前請求匹配上了,搜尋將會停止,直接使用這個這個 location.
  3. 如果第二步沒有匹配上,nginx 會按照如下步驟繼續搜尋最長字首匹配: 3.1 如果最長字首匹配有^~這個modifier,nginx 會停止搜尋並直接使用這個 location. 3.2 如果沒有使用 ^~,暫存這個 location並且繼續搜尋.
  4. 只要最長字首匹配被暫存和選中,nginx 就會看當前的 location 是否有大小寫敏感的 RE(~~*),第一個匹配上這種會被當做有效的 location來處理這個請求.
  5. 如果沒有 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

相關文章