Nginx Location 路徑匹配

Dxtr發表於2018-11-06

Nginx 通過不同的 location 配置來匹配訪問的 uri. 這樣便可以做到對不同的 uri 執行不同的操作.

location 的路徑匹配可以分為兩種: 字首匹配和正則匹配, 基本語法為:

location [ = | ~ | ~* | ^~ ] uri {
    ... 
}
複製程式碼

其中, =, ^~, ~~*分別表示:
=: 精確匹配 => 字首匹配;
^~: 優先字首匹配 => 字首匹配;
~: 正則匹配(大小寫敏感) => 正則匹配;
~*: 正則匹配(大小學不敏感) => 正則匹配;

匹配規則

  1. 首先檢查使用字首匹配的 location, 找到最長匹配項並且記錄下來
  2. 如果找到了精確匹配的 location(=), 則結束查詢, 直接使用該 location 的配置; 如果最長匹配的 location 是優先字首匹配(^~), 也結束查詢, 使用該 location 的配置
  3. 然後按照順序檢查使用正則匹配的 location, 一旦匹配則結束查詢, 直接使用匹配的 location 的配置
  4. 如果找完所有的正則匹配後還是沒有匹配到, 則採用字首匹配查詢時記錄下來的的最長匹配項的 location 的配置

栗子:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}
複製程式碼

以上配置中:
/: 精確匹配 A, 則直接採用配置 A, 不再繼續檢查.
/index.html: 首先檢查字首匹配, 最長匹配為 B; 然後檢查正則匹配, 未匹配到, 則採用配置 B.
/documents/documents.html/: 首先檢查字首匹配, 最長匹配為 C; 然後檢查正則匹配, 未匹配到, 則採用配置配 C.
/images/pic.jpg: 首先檢查字首匹配, 匹配到最長匹配為 D, 此時 D 為優先字首匹配, 不再繼續檢查, 直接採用配置 D;
/documents/pic.jpg: 首先檢查字首匹配, 最長匹配為 C; 然後按照順序檢查正則匹配, 匹配了 E, 則停止檢查, 直接採用配置 D'

字首匹配中的 slash 字尾

如果在 location 字首匹配中以斜線 / 結尾, 並且 location 中的配置為proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass 或者 grpc_pass 中的一個. 在訪問的時候如果沒有斜線結尾, 那麼 Nginx 會預設返回帶斜線的 301 重定向. 比如:

location /doc-1/ {
    proxy_pass http://localhost:3000;
}
複製程式碼

不帶 slash 訪問

不帶 slash 訪問
帶slash 訪問
帶slash 訪問

但是如果在配置 location 的時候沒有以斜槓結尾, 造成的結果是當你以加斜槓的 uri 去訪問的時候, Nginx 無法匹配該 uri.

location /doc-2 {
    proxy_pass http://localhost:3000;
}
複製程式碼

不帶 slash 訪問

不帶 slash 訪問
帶 slash 訪問
帶 slash 訪問

參考:
ngx_http_core_module.html#location

相關文章