Nginx 的location配置詳解


Nginx 允許用戶定義 Location block ,並指定一個匹配模式(pattern)匹配特定的 URI。除了簡單的字符串(比如文件系統路徑),還允許使用更爲複雜的匹配模式(pattern)。

Location block 的基本語法形式是:

    location [=|~|~*|^~|@] pattern { ... }

[=|~|~*|^~|@] 被稱作 location modifier ,這會定義 Nginx 如何去匹配其後的 pattern ,以及該 pattern 的最基本的屬性(簡單字符串或正則表達式)。


------- 關於 location modifier -------

1. =

這會完全匹配指定的 pattern ,且這裏的 pattern 被限制成簡單的字符串,也就是說這裏不能使用正則表達式。

Example:

server {

    server_name website.com;

    location = /abcd {

    […]

    }

}

匹配情況:

    http://website.com/abcd        # 正好完全匹配

    http://website.com/ABCD        # 如果運行 Nginx server 的系統本身對大小寫不敏感,比如 Windows ,那麼也匹配

    http://website.com/abcd?param1m2    # 忽略查詢串參數(query string arguments),這裏就是 /abcd 後面的 ?param1m2

    http://website.com/abcd/    # 不匹配,因爲末尾存在反斜槓(trailing slash),Nginx 不認爲這種情況是完全匹配

    http://website.com/abcde    # 不匹配,因爲不是完全匹配


2. (None)

可以不寫 location modifier ,Nginx 仍然能去匹配 pattern 。這種情況下,匹配那些以指定的 patern 開頭的 URI,注意這裏的 URI 只能是普通字符串,不能使用正則表達式。

Example:

server {

    server_name website.com;

    location /abcd {

    […]

    }

}

匹配情況:

    http://website.com/abcd        # 正好完全匹配

    http://website.com/ABCD        # 如果運行 Nginx server 的系統本身對大小寫不敏感,比如 Windows ,那麼也匹配

    http://website.com/abcd?param1m2    # 忽略查詢串參數(query string arguments),這裏就是 /abcd 後面的 ?param1m2

    http://website.com/abcd/    # 末尾存在反斜槓(trailing slash)也屬於匹配範圍內

    http://website.com/abcde    # 仍然匹配,因爲 URI 是以 pattern 開頭的


3. ~

這個 location modifier 對大小寫敏感,且 pattern 須是正則表達式

Example:

server {

    server_name website.com;

    location ~ ^/abcd$ {

    […]

    }

}

匹配情況:

    http://website.com/abcd        # 完全匹配

    http://website.com/ABCD        # 不匹配,~ 對大小寫是敏感的

    http://website.com/abcd?param1m2    # 忽略查詢串參數(query string arguments),這裏就是 /abcd 後面的 ?param1m2

    http://website.com/abcd/    # 不匹配,因爲末尾存在反斜槓(trailing slash),並不匹配正則表達式 ^/abcd$

    http://website.com/abcde    # 不匹配正則表達式 ^/abcd$

注意:對於一些對大小寫不敏感的系統,比如 Windows ,~ 和 ~* 都是不起作用的,這主要是操作系統的原因。


4. ~*

與 ~ 類似,但這個 location modifier 不區分大小寫,pattern 須是正則表達式

Example:

server {

    server_name website.com;

    location ~* ^/abcd$ {

    […]

    }

}

匹配情況:

    http://website.com/abcd        # 完全匹配

    http://website.com/ABCD        # 匹配,這就是它不區分大小寫的特性

    http://website.com/abcd?param1m2    # 忽略查詢串參數(query string arguments),這裏就是 /abcd 後面的 ?param1m2

    http://website.com/abcd/    # 不匹配,因爲末尾存在反斜槓(trailing slash),並不匹配正則表達式 ^/abcd$

    http://website.com/abcde    # 不匹配正則表達式 ^/abcd$


5. ^~

匹配情況類似 2. (None) 的情況,以指定匹配模式開頭的 URI 被匹配,不同的是,一旦匹配成功,那麼 Nginx 就停止去尋找其他的 Location 塊進行匹配了(與 Location 匹配順序有關)


6. @

用於定義一個 Location 塊,且該塊不能被外部 Client 所訪問,只能被 Nginx 內部配置指令所訪問,比如 try_files or error_page


------- 搜索順序以及生效優先級 -------

因爲可以定義多個 Location 塊,每個 Location 塊可以有各自的 pattern 。因此就需要明白(不管是 Nginx 還是你),當 Nginx 收到一個請求時,它是如何去匹配 URI 並找到合適的 Location 的。

要注意的是,寫在配置文件中每個 Server 塊中的 Location 塊的次序是不重要的,Nginx 會按 location modifier 的優先級來依次用 URI 去匹配 pattern ,順序如下:

    1. =

    2. (None)    如果 pattern 完全匹配 URI(不是隻匹配 URI 的頭部)

    3. ^~

    4. ~ 或 ~*

    5. (None)    pattern 匹配 URI 的頭部


7.匹配案例

location  = / {

  # 精確匹配 / ,主機名後面不能帶任何字符串

  [ configuration A ] 

}

location  / {

  # 因爲所有的地址都以 / 開頭,所以這條規則將匹配到所有請求

  # 但是正則和最長字符串會優先匹配

  [ configuration B ] 

}

location /documents/ {

  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜索

  # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條

  [ configuration C ] 

}

location ~ /documents/Abc {

  # 匹配任何以 /documents/ 開頭的地址,匹配符合以後,還要繼續往下搜索

  # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條

  [ configuration CC ] 

}

location ^~ /p_w_picpaths/ {

  # 匹配任何以 /p_w_picpaths/ 開頭的地址,匹配符合以後,停止往下搜索正則,採用這一條。

  [ configuration D ] 

}

location ~* \.(gif|jpg|jpeg)$ {

  # 匹配所有以 gif,jpg或jpeg 結尾的請求

  # 然而,所有請求 /p_w_picpaths/ 下的圖片會被 config D 處理,因爲 ^~ 到達不了這一條正則

  [ configuration E ] 

}

location /p_w_picpaths/ {

  # 字符匹配到 /p_w_picpaths/,繼續往下,會發現 ^~ 存在

  [ configuration F ] 

}

location /p_w_picpaths/abc {

  # 最長字符匹配到 /p_w_picpaths/abc,繼續往下,會發現 ^~ 存在

  # F與G的放置順序是沒有關係的

  [ configuration G ] 

}

location ~ /p_w_picpaths/abc/ {

  # 只有去掉 config D 纔有效:先最長匹配 config G 開頭的地址,繼續往下搜索,匹配到這一條正則,採用

    [ configuration H ] 

}

location ~* /js/.*/\.js



順序 no優先級:

(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/)

上面的匹配結果

按照上面的location寫法,以下的匹配示例成立:

/ -> config A

精確完全匹配,即使/index.html也匹配不了

/downloads/download.html -> config B

匹配B以後,往下沒有任何匹配,採用B

/p_w_picpaths/1.gif -> configuration D

匹配到F,往下匹配到D,停止往下

/p_w_picpaths/abc/def -> config D

最長匹配到G,往下匹配D,停止往下

你可以看到 任何以/p_w_picpaths/開頭的都會匹配到D並停止,FG寫在這裏是沒有任何意義的,H是永遠輪不到的,這裏只是爲了說明匹配順序

/documents/document.html -> config C

匹配到C,往下沒有任何匹配,採用C

/documents/1.jpg -> configuration E

匹配到C,往下正則匹配到E

/documents/Abc.jpg -> config CC

最長匹配到C,往下正則順序匹配到CC,不會往下到E


8.實際使用建議

所以實際使用中,個人覺得至少有三個匹配規則定義,如下:

#直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。

#這裏是直接轉發給後端應用服務器了,也可以是一個靜態首頁

# 第一個必選規則

location = / {

    proxy_pass http://tomcat:8080/index

}

# 第二個必選規則是處理靜態文件請求,這是nginx作爲http服務器的強項

# 有兩種配置模式,目錄匹配或後綴匹配,任選其一或搭配使用

location ^~ /static/ {

    root /webroot/static/;

}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {

    root /webroot/res/;

}

#第三個規則就是通用規則,用來轉發動態請求到後端應用服務器

#非靜態文件請求就默認是動態請求,自己根據實際把握

location / {

    proxy_pass http://tomcat:8080/

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章