深入解析 Nginx location 匹配規則
Contents
最近公司專案設定 API Gateway 無法順利導向後端 API 位置。檢查 Azure 的配置時發現,Azure 的路由規則是有上下順序的,但 Nginx 並不是這樣運作。經過研究才發現 Nginx 的 location 匹配規則和 Azure API Gateway 的邏輯完全不同,這裡就做個完整整理。
核心匹配順序 (從高到低)
Nginx 在處理請求時,會遵循以下邏輯來決定最終使用的 location:
| 順序 | 修飾符 | 匹配類型 | 匹配規則與行為 |
|---|---|---|---|
| 1 | = |
精確匹配 | 全字串完全符合。一旦命中,立刻停止搜尋,直接採用此設定。 |
| 2 | ^~ |
前綴匹配 (阻斷) | 如果該前綴是「最長匹配」,立即停止搜尋,不檢查正規表達式。 |
| 3 | (無修飾符) | 普通前綴匹配 | 尋找最長符合的前綴並暫存起來,但會繼續往下檢查正規表達式。 |
| 4 | ~ / ~* |
正規表達式 | 依據在設定檔中出現的先後順序比對。第一個命中的立刻停止搜尋。 |
一句話秒懂
「精確優先;最長匹配帶
^~ 直接贏;否則交給正規表達式按順序比對(先到先得),全都沒命中才由最長前綴保底。」完整的演算法決策流程
如果我們把 Nginx 的「大腦」拆解成三個階段,邏輯會變得非常清晰:
第一階段:前綴字串比對 (Literal/Prefix Strings)
- 檢查
=精確匹配:如果有完全一致的 URI(例如/index.html),直接採用並結束。 - 尋找最長前綴:找出所有普通字串(包含無修飾與
^~)中,匹配長度最長的那一個。 - 判斷是否阻斷:
- 如果這個「最長匹配」帶有
^~修飾符,Nginx 認為這已經足夠明確,會直接採用此設定並停止搜尋。 - 如果只是普通字串(無修飾),Nginx 會將此結果暫存起來作為備選方案,然後進入下一階段。
- 如果這個「最長匹配」帶有
第二階段:正規表達式比對 (Regular Expressions)
- 按順序掃描
~或~*:從設定檔由上往下逐行讀取。- 只要有任何一個正規表達式成功匹配,就會立即採用此規則,並丟棄第一階段暫存的備選方案。
第三階段:最終終點
- 保底機制:如果所有的正規表達式都沒有匹配成功,Nginx 才會最後採用第一階段暫存的最長普通前綴。
實戰範例與差異對比
透過以下配置,你可以清楚看到不同修飾符帶來的行為差異:
|
|
參考: - nginx location 匹配規則 – 煎炸熊の記事本
容易混淆的誤區:網址中間或結尾帶 *
很多人會把 Nginx 的 location 當成一般的檔案搜尋(像 Windows 搜尋 *.txt 那樣用通配符),以為可以這樣寫:
❌ location /api/*/user (想代表中間任意字元)
❌ location /images/* (想代表路徑下的所有檔案)
:::warning
⚠️ 注意:在 Nginx 的普通前綴匹配中,星號 * 沒有任何特殊功能,它會被當成一個「真正的星號字元」!
:::
location 預設路徑
location /:比對所有以 / 開頭的請求。由於所有路徑都以 / 開頭,當找不到更精確的比對時,它會作為「預設路徑」。
|
|
加碼:Azure API Gateway 規則
PathPattern 重點整理
簡短說明
PathPattern 是一組以 / 開頭的路徑比對字串,可使用 * 作為萬用字元來匹配多種路徑。查詢字串(? 之後)與片段(# 之後)不會包含在比對範圍中,且路徑比對不分大小寫。 目前頁面 目前頁面
支援的範例與限制(快速表格)
| 範例 PathPattern | 是否支援 | 備註 |
|---|---|---|
/images/* |
是 | 支援以資料夾為單位的萬用比對。 目前頁面 |
/images* |
是 | 可匹配 /images 開頭的任意字串。 目前頁面 |
/images/*.jpg |
否 | 不支援在路徑中以萬用字元搭配副檔名的精確檔案比對。 目前頁面 |
/*.jpg |
否 | 不支援以此方式直接比對所有 JPG 檔案。 目前頁面 |
/Repos/*/Comments/* |
否 | 不支援多段中間夾雜萬用段的複雜模式。 目前頁面 |
/CurrentUser/Comments/* |
是 | 支援具體多層路徑末端為萬用的情形。 目前頁面 |
參考: Azure Application Gateway URL-based content routing overview | Microsoft Learn