nginx location if 的匹配規則


cation匹配命令

~      #波浪線表示執行一個正則匹配,區分大小寫
~*    #表示執行一個正則匹配,不區分大小寫
^~    #^~表示普通字符匹配,不是正則匹配。如果該選項匹配,只匹配該選項,不匹配別的選項,一般用來匹配目錄
=      #進行普通字符精確匹配
@     #"@" 定義一個命名的 location,使用在內部定向時,例如 error_page, try_files

 

 

參考:https://segmentfault.com/a/1190000002797606

 

 

location 優先級官方文檔

 

1. Directives with the = prefix that match the query exactly. If found, searching stops.

2. All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops.

3. Regular expressions, in order of definition in the configuration file.

4. If #3 yielded a match, that result is used. Else the match from #2 is used.

 

1. =前綴的指令嚴格匹配這個查詢。如果找到,停止搜索。

2. 所有剩下的常規字符串,最長的匹配。如果這個匹配使用^前綴,搜索停止。

3. 正則表達式,在配置文件中定義的順序。

4. 如果第3條規則產生匹配的話,結果被使用。否則,如同從第2條規則被使用。

 

順序 no優先級: (location =)   >  (location ^~ 路徑 最長匹配的意思) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/)

 

例如:

location  = / {
  # 只匹配"/".
  [ configuration A ] 
}
location  / {
  # 匹配任何請求,因為所有請求都是以"/"開始
  # 但是更長字符匹配或者正則表達式匹配會優先匹配
  [ configuration B ] 
}
location ^~ /p_w_picpaths/ {
  # 匹配任何以 /p_w_picpaths/ 開始的請求,並停止匹配 其它location
  [ configuration C ] 
}
location ~* \.(gif|jpg|jpeg)$ {
  # 匹配以 gif, jpg, or jpeg結尾的請求. 
  # 但是所有 /p_w_picpaths/ 目錄的請求將由 [Configuration C]處理.   
  [ configuration D ] 
}

 

 

 

我的疑問1 : 如果是以下的 

  • /p_w_picpaths/1.gif -> 會匹配C還是D呢?  會按順序匹配到C。因為都是正則所以按順序匹配到了C

location ~ /p_w_picpaths/ {
  # 匹配任何以 /p_w_picpaths/ 開始的請求,並停止匹配 其它location
  [ configuration C ] 
}
location ~* \.(gif|jpg|jpeg)$ {
  # 匹配以 gif, jpg, or jpeg結尾的請求. 
  # 但是所有 /p_w_picpaths/ 目錄的請求將由 [Configuration C]處理.   
  [ configuration D ] 
}

 

 

我的疑問2: 如果是以下的。會匹配到D ,因為正則匹配到優先級大於部分起始路徑。

location  /p_w_picpaths/ {
  # 匹配任何以 /p_w_picpaths/ 開始的請求,並停止匹配 其它location
  [ configuration C ] 
}
location ~* \.(gif|jpg|jpeg)$ {
  # 匹配以 gif, jpg, or jpeg結尾的請求. 
  # 但是所有 /p_w_picpaths/ 目錄的請求將由 [Configuration C]處理.   
  [ configuration D ] 
}

 

 

 

 

 

if 條件判斷:

參考:

http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_rewrite_module.html#if

 

語法: if (condition) { ... }
默認值:
上下文: serverlocation

計算指定的condition的值。如果為真,執行定義在大括號中的rewrite模塊指令,並將if指令中的配置指定給請求。if指令會從上一層配置中繼承配置。

條件可以是下列任意一種:

  • 變量名;如果變量值為空或者是以“0”開始的字符串,則條件為假;

  • 使用“=”和“!=”運算符比較變量和字符串;

  • 使用“~”(大小寫敏感)和“~*”(大小寫不敏感)運算符匹配變量和正則表達式。正則表達式可以包含匹配組,匹配結果后續可以使用變量$1..$9引用。如果正則表達式中包含字符“}”或者“;”,整個表達式應該被包含在單引號或雙引號的引用中。

  • 使用“-f”和“!-f”運算符檢查文件是否存在;

  • 使用“-d”和“!-d”運算符檢查目錄是否存在;

  • 使用“-e”和“!-e”運算符檢查文件、目錄或符號鏈接是否存在;

  • 使用“-x”和“!-x”運算符檢查可執行文件;

 

舉例:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}

if ($request_method = POST) {
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

if ($invalid_referer) {
    return 403;
}

 

案例每個用戶的guid存在cookie中要存入nginx日志 如果存在的話:

    set $guid "-";

    if ( $http_cookie ~* "guid=(\S+)(;.*|$)"){

        set $guid $1;

    }

 

內嵌變量 $invalid_referer的值是通過 valid_referers指令設置的。

 

補充正則表達式知識:

參考:https://regex101.com/

(?:;|$)
(;|$)

兩者的區別即 ?:的作用。加上?:在分組中表示不捕捉這個分組,在后面不可以引用 Non-capturing group 

(?:;|$)

Capturing Group 

(;|$)

 

 

 

 

rewrite 模塊

 

重寫語法:

http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_rewrite_module.html#if

 

語法: rewrite regex replacement [flag];
默認值:
上下文: serverlocationif

如果指定的正則表達式能匹配URI,此URI將被replacement參數定義的字符串改寫。rewrite指令按其在配置文件中出現的順序執行。flag可以終止后續指令的執行。如果replacement的字符串以“http://”或“https://”開頭,nginx將結束執行過程,並返回給客戶端一個重定向。

可選的flag參數可以是其中之一:

  • last

  • 停止執行當前這一輪的ngx_http_rewrite_module指令集,然后查找匹配改變后URI的新location;

  • break

  • 停止執行當前這一輪的ngx_http_rewrite_module指令集;

  • redirect

  • 在replacement字符串未以“http://”或“https://”開頭時,使用返回狀態碼為302的臨時重定向;

  • permanent

  • 返回狀態碼為301的永久重定向。

 

 

如果URI中含有參數(/app/test.php?id=5),默認情況下參數會被自動附加到替換串上,可以通過在替換串的末尾加上?標記來解決這一問題。
例如:
 

復制代碼代碼示例:

rewrite ^/test(.*)$ http://www.it.net.cn/home  permanent;
訪問http://www.it.net.cn/test?id=5 會跳轉到 http://www.it.net.cn/home?id=5
 

例如:如果將類似URL /photo/123456 重定向到 /path/to/photo/12/1234/123456.png
 

復制代碼代碼示例:

Rewrite "/photo/([0-9]{2})([0-9]{2})([0-9]{2})" /path/to/photo/$1/$1$2/$1$2$3.png ;

 

 

 

set指令。這里的變量名和php的語法差不多。變量名前面定義$代表定義變量(set)或者引用變量。

Syntax: set $variable value;
Default:
Context: serverlocationif

Sets a value for the specified variable. The value can contain text, variables, and their combination.

 

 

轉自:https://blog.51cto.com/cuidehua/1874770


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM