Nginx路徑匹配規則詳解

jopen 10年前發布 | 118K 次閱讀 Nginx Web服務器

本節要討論Nginx如何為一個請求選擇匹配的location進行處理。

如下配置文件:

server {
    listen         80 default_server;
    server_name  itravel.smartcom.cc itravel-beta.huawei.com;
    client_max_body_size  8M;
    server_tokens  off;
    root   /data/web/itravel2.smartcom.cc/trunk/htdocs;

error_page     404  /404.htm;
error_page    500 502 503 504  /50x.htm;

location / {
    #root   /data/web/itravel2.smartcom.cc/trunk/htdocs;
    index  index.php index.html index.htm;
    if (!-e $request_filename) {
        rewrite ^(.+)\.html$ $1.php last;
    }
}

location /static/js/ {
    #root /data/web/itravel2.smartcom.cc/trunk/htdocs;
    concat on;
    concat_types text/javascript;
}

location /static/css/ {
    #root /data/web/itravel2.smartcom.cc/trunk/htdocs;
    concat on;
    concat_types text/css;
}

location /api { }

location ~/\.ht { }


location ~ ^/~([^/]+)(/?.*)$ { }

location ~ \.do$ { }

location ~ \.(jpg|jpeg|gif|png|ico|css|tgz|gz|bz2|pdf|txt|tar|bmp|js|mov) { }

location ~ /trip/ { }

location /trip/ { }

location ~ \.php$ { }

}</pre>

第一步:請求URI(路徑)規范化。

所謂規范化,就是先將URI中形如“%XX”的編碼字符進行解碼,再解析URI中的相對路徑“.”和“..”部分, 另外還可能會壓縮相鄰的兩個或多個斜線成為一個斜線。

舉例說明:若REQUEST_URI為//trip/t.php,則規范化后為/trip/t.php,Nginx將規范前的值存放在$request_uri中,而規范化后的值存放在$uri中。

其中,$request_uri和$uri為Nginx內嵌變量。

第二步:請求URI路徑匹配。

首先需要明確Nginx中將路徑匹配分為兩類:

  1. 前綴路徑匹配,即前綴字符串定義的路徑,如上配置文件中“/,/static/js/,/static/css/,/api,/trip/”
  2. 正則表達式路徑匹配,即使用正則表達式需要在路徑開始添加“~*”前綴 (不區分大小寫),或者“~”前綴(區分大小寫)。如上配置文件中“/\.ht,^/~([^/]+)(/?.*)$,\.do$,/trip/, \.php$,\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar||bmp|rtf|js|mov)”

其次為了根據請求URI查找路徑,需要明確路徑匹配的順序:

Nginx首先檢查前綴字符串定義的路徑 (前綴路徑),在這些路徑中找到能最精確匹配請求URI的路徑。然后Nginx按在配置文件中的出現順序檢查正則表達式路徑,匹配上某個路徑后即停止匹配并使用該路徑的配置,否則使用最大前綴匹配的路徑的配置。

舉例說明:請求/trip/t.php,首先進行前綴路徑匹配,最精確的前綴路徑為/trip/,接下來進行正則表達式匹配,匹配到\.php$,從而進行location ~ \.php$ { }處理請求。反之若請求的是/trip/t.html,由于沒有正則表達式匹配到該URI,故匹配最精確的前綴路徑匹配,即進入location /trip/ { }處理請求。若想不論是請求/trip/t.php,還是/trip/t.html,都匹配到/trip/進行處理,則可以使用location ^~ /trip/ { },這樣Nginx就不會再檢查正則表達式了。

備注:

路徑可以嵌套,但有例外。
在不區分大小寫的操作系統(諸如Mac OS X和Cygwin)上,前綴匹配忽略大小寫(0.7.7)。但是,比較僅限于單字節的編碼區域(one-byte locale)。
正則表達式中可以包含匹配組(0.7.40),結果可以被后面的其他指令使用。
如果最大前綴匹配的路徑以“^~”開始,那么Nginx不再檢查正則表達式。
在0.7.1到0.8.41的所有Nginx中,如果請求匹配的前綴字符串路徑并沒有“=”或“^~”前綴, 路徑查找過程仍然會停止,而不進行正則表達式匹配。

而且,使用“=”前綴可以定義URI和路徑的精確匹配。如果發現匹配,則終止路徑查找。 比如,如果請求“/”出現頻繁,定義“location = /”可以提高這些請求的處理速度, 因為查找過程在第一次比較以后即結束。這樣的路徑明顯不可能包含嵌套路徑。

擴展閱讀:

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!