Nginx Location 匹配規則詳解與實例

Web2026-09-20TryQuickToolBox

您可能曾經調整過 Nginx 設定、重新載入後,卻發現您的 location 區塊似乎沒有生效。也許靜態檔案請求被 PHP 處理器攔截了,或者 API 路由被一個 catch-all 規則吞掉了。罪魁禍首通常是 Nginx 的 location 匹配演算法——它並不像表面上看起來那麼簡單。

在本指南中,我們將透過您可以實際測試的範例,詳細解析 Nginx 如何選擇 location 區塊。讀完後,您將確切了解哪個區塊會勝出以及原因。

Nginx Location 匹配的運作方式

當請求進來時,Nginx 會將 URI 與所有已定義的 location 區塊進行比對。匹配過程遵循以下順序:

  1. 精確匹配(=)——優先順序最高。若找到,Nginx 會停止並使用它。
  2. 最長前綴匹配——Nginx 會記住最長匹配的前綴 location。
  3. 正則表達式匹配(~ 或 ~*)——按出現順序檢查。第一個匹配的正則表達式勝出,並覆蓋前綴匹配(除非使用了 ^~)。
  4. 帶有 ^~ 的前綴匹配——如果最長匹配的前綴帶有 ^~,Nginx 會跳過正則檢查並使用它。
  5. 如果沒有正則表達式匹配,則使用最長前綴匹配。

這就是核心演算法。讓我們看看實際運作情況。

Location 修飾符:快速參考

修飾符語法匹配類型優先順序
=location = /path精確最高
^~location ^~ /path前綴(不使用正則)高
~location ~ \.php$正則(區分大小寫)中
~*location ~* \.(jpg|png)$正則(不區分大小寫)中
無location /path前綴最低

實際範例 1:靜態檔案與 PHP

考慮這個常見設定:

server {
    listen 80;
    server_name example.com;

    location / {
        root /var/www/html;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
}

對 /index.php 的請求會匹配正則 \.php$,因此會交給 PHP-FPM 處理。對 /logo.png 的請求不匹配正則,因此會回退到前綴 / 並提供靜態檔案。很簡單,對吧?

但如果您想將 /uploads/photo.php 作為靜態檔案提供(也許它實際上是一張圖片)呢?您可以加入一個精確匹配:

location = /uploads/photo.php {
    root /var/www/html;
}

現在這個精確匹配的優先順序高於正則表達式。

實際範例 2:使用前綴和正則的 API 路由

假設您有一個位於 /api/ 下的 API,並且您想將所有請求代理到後端,但健康檢查除外,它應該返回靜態回應。

location = /api/health {
    return 200 "OK";
}

location /api/ {
    proxy_pass http://backend;
}

location ~ ^/api/v[0-9]+/special {
    proxy_pass http://special-backend;
}

讓我們追蹤 /api/health:精確匹配勝出,返回 200。對於 /api/users:沒有精確匹配,也沒有正則匹配(不匹配 special),因此使用最長前綴 /api/。對於 /api/v1/special:正則匹配,因此它覆蓋前綴並轉到 special-backend。

這展示了正則如何覆蓋前綴匹配。如果您希望前綴始終勝出,則應改用 ^~。

實際範例 3:^~ 的威力

想像您有一個 /static/ 目錄,其中的檔案即使以 .php 結尾,也絕不應由 PHP 處理。使用 ^~ 可確保 Nginx 不檢查正則 location。

location ^~ /static/ {
    root /var/www/html;
}

location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}

對 /static/script.php 的請求會匹配前綴 ^~ /static/。由於 ^~,Nginx 會跳過正則檢查並直接提供該檔案。如果沒有 ^~,正則會匹配,PHP-FPM 將執行它——這是一個潛在的安全風險。

常見陷阱及如何避免

除錯 Location 匹配

如果您不確定正在使用哪個 location,請在 Nginx 中啟用除錯記錄。在您的 server 區塊中加入 error_log /var/log/nginx/error.log debug;,重新載入,然後檢查記錄。您會看到類似 test location: "/api/users" 和 using configuration "/api/" 的訊息。

或者,暫時在每個 location 中使用 return 200 "matched: /api/"; 來查看哪個會回應。

常見問題

Nginx location 修飾符的優先順序為何?

精確匹配(=)最高,然後是帶有 ^~ 的最長前綴,然後是按順序的正則(~ 或 ~*),最後是不帶 ^~ 的最長前綴匹配。

正則 location 可以覆蓋前綴 location 嗎?

可以,除非前綴 location 使用了 ^~。正則 location 會在最長前綴匹配之後檢查,如果正則匹配,它的優先順序高於一般前綴。

如何僅針對特定檔案匹配 location?

使用帶有 = 的精確匹配,例如 location = /favicon.ico。這確保只匹配該確切的 URI。

精通您的 Nginx 設定

了解 location 匹配是建立可靠 Nginx 設定的關鍵。使用 nginx -t 測試您的設定,並在遇到疑問時使用除錯記錄。如果您正在處理 Nginx 記錄並需要分析流量模式,請試試我們的 Nginx Log Analyzer,快速解析並視覺化您的記錄。