nginx rewrite 模塊

nginx rewrite模塊

nginx官方用戶手冊:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

rewrite和location的功能有點相像,都能實現(xiàn)跳轉(zhuǎn),主要區(qū)別在于rewrite常用于同一域名內(nèi)更改獲取資源的路徑,而location是對一類路徑做控制訪問和反向代理,可以proxy_pass到其他服務(wù)器,在此說明下rewrite和location的執(zhí)行先后順序:

  1. 執(zhí)行server塊中的rewrite;
  2. 執(zhí)行l(wèi)ocation;
  3. 執(zhí)行l(wèi)ocation中的rewrite;

如果其中某步url被重寫,則重新循環(huán)執(zhí)行2-3步,直到找到按該url可以訪問的文件,循環(huán)次數(shù)不超過10。

rewrite 中用到的指令

if (條件) {} #設(shè)定條件,再進(jìn)行重寫
set #設(shè)置變量
return #返回狀態(tài)碼
break #跳出rewrite
rewrite #重寫
rewrite_log
uninitialized_variable_warn
Internal Implementation

break

參數(shù)項: break,用于停止執(zhí)行rewrite模塊的指令,但是其他模塊不受影響。

配置位置: if, server, location

示例:

server {
        listen       80;
        server_name  _;
        #===== break && rewrite test =====
        #這里如果注釋掉break,所有請求進(jìn)來都是返回http200,this is breaktest...
        break;
        return 200 "this is breaktest...";
        location = /breaktest {
            break;
            return 200 $request_uri;
            proxy_pass http://10.0.0.2/other;
        }
        location / {
            return 200 $request_uri;
        }

測試鏈接:http://10.0.0.2/breaktest ,請求到達(dá)server塊后,被break終止執(zhí)行rewrite指令集,return屬于rewrite模塊指令集,所以return 200 “this is breaktest...”不會執(zhí)行;因為沒有返回結(jié)果,所以繼續(xù)執(zhí)行l(wèi)ocation匹配,請求匹配到location = /breaktest{}之后,break終止return 200 $request_uri,而proxy_pass屬于ngx_http_proxy_module,仍會繼續(xù)執(zhí)行,反向代理后的新url匹配到location /{},因此最終返回結(jié)果為 http200,/other,如下圖:

set

配置位置: if, server, location

用于為變量賦值

server {
        listen       80;
        server_name  _;
        #===== break && rewrite test =====
        #這里如果注釋掉break,所有請求進(jìn)來都是返回http200,this is breaktest...
        break;
        return 200 "this is breaktest...";
        location = /breaktest {
            break;
            return 200 $request_uri;
            proxy_pass http://10.0.0.2/other;
        }
        location / {
            #set賦值,可以直接賦字符串,或是變量,如下是變量和字符串的組合
            set $set_value_test “112233 $request_uri”;
            return 200 $set_value_test;
        }

if

配置位置: server, location

用于依據(jù)指定的條件,決定是否執(zhí)行 if 塊中的語句

語法:

#判斷條件為 ture 時,執(zhí)行{}塊中語句,為 false 時,不執(zhí)行.
if (判斷條件) {
    ... ...;
}

判斷條件:

  1. 變量值

    變量值為空或為0,都為false

set $if_value_test “0”;
     #注意這里if、()和{}要空格,否則會報錯..略坑,不過這也是代碼規(guī)范了
    if ($if_value_test) {
         #不會執(zhí)行,因為$if_value_test值為0,false
         return 200;
    }
  1. 變量與字符串比較

    = 為等于,!= 為不等于

set $if_value_test “hello”;
    if ($if_value_test = "hello") {
        #變量和字符相等,邏輯為true,執(zhí)行
        return 200;
    }
  1. 變量與正則表達(dá)式匹配
參數(shù) 說明
~ 與指定正則表達(dá)式匹配時返回 True,判斷匹配與否時區(qū)分字符大小寫
~* 與指定正則表達(dá)式匹配時返回 True,判斷匹配與否時不區(qū)分字符大小寫
!~ 與指定正則表達(dá)式不匹配時返回 True,判斷匹配與否時區(qū)分字符大小寫
!~* 與指定正則表達(dá)式不匹配時返回 True,判斷匹配與否時不區(qū)分字符大小寫
if ($request_uri ~ "^/breaktest$") {
      #測試鏈接http://10.0.0.2/breaktest,最終返回http200
      return 200;
}
  1. 文件及目錄匹配
參數(shù) 說明
-f , !-f 判斷指定的路徑是否為存在且為文件
-d , !-d 判斷指定的路徑是否為存在且為目錄
-e , !-e 判斷指定的路徑是否存在,文件或目錄均可
-x , !-x 判斷指定路徑的文件是否存在且可執(zhí)行

return

配置位置: if, server, location

參數(shù)值: return code [text] 返回狀態(tài)碼及文本,return url重定向,turn code 重定向

if ($request_uri ~ "^/breaktest$") {
#測試鏈接http://10.0.0.2/breaktest,最終返回http200
return 200 http://www.baidu.com/;
}

rewrite

配置位置:if, server, location

參數(shù)值: rewrite regex replacement [flag],用于以正則表達(dá)式匹配特定格式的url并重寫url.

regex為正則表達(dá)式,replacement為重寫的內(nèi)容,flag為rewrite的標(biāo)識位

replacement:重寫的url帶http,表示重定向

location / {
    #測試鏈接http://10.0.0.2/test/,被重定向到百度首頁,后面的語句不會再執(zhí)行
    rewrite /test/(.*) http://www.baidu.com;
    set $set_value_test "112233 $request_uri";
    return 200 $set_value_test;
}

replacement:重寫的url不帶http,單純的重寫url

location / {
#測試鏈接http://10.0.0.2/test/,匹配到location /{}后url被重寫為http://192.168.88.38/breaktest,繼續(xù)搜索匹配
#匹配到location = /breaktest{},最終返回http200及this is breaktest
            rewrite /test/(.*) /breaktest;
        }
        location = /breaktest {
           return 200 "this is breaktest";
        }
flag:

用于設(shè)置重寫url后的進(jìn)一步操作,有break,last,redirect,permanent,不帶flag

標(biāo)記 特點 說明
無flag 不改變?yōu)g覽器地址,**返回200或404等,對用戶透明 多個rewrite指令順序執(zhí)行,當(dāng)location中沒有可執(zhí)行的rewrite模塊指令時,重新發(fā)起一次location匹配,下面說明各個flag的用途
last ( default ) 不改變?yōu)g覽器地址,返回200或404等,對用戶透明 終止執(zhí)行rewrite模塊指令集,并開始搜尋重寫url后匹配的location
break 不改變?yōu)g覽器地址,返回200或404等,對用戶透明 用于停止執(zhí)行rewrite模塊的指令,但是其他模塊不受影響。
redirect 改變?yōu)g覽器地址 返回302臨時重定向
permanent 改變?yōu)g覽器地址 返回301永久重定向
 location / {
        #測試鏈接http://10.0.0.2/test1,匹配到location / {}
           rewrite ^/test1 /test2;#被重寫為/test2,繼續(xù)往下執(zhí)行rewrite
           rewrite ^/test2 /test3;#被重寫為/test3,往下沒有可執(zhí)行的rewrite模塊指令,發(fā)起一次location匹配,匹配到location /test3 {},最終返回http200及/test3
        }
        location /test2 {
            return 200 "/test2";
        }
        location /test3 {
            return 200 "/test3";
        }

last和break的區(qū)別在于,last會發(fā)起新的location匹配,而break不會。

location / {
           rewrite ^/test1 /test2;
           rewrite ^/test2 /test3 last;
           rewrite ^/test3 /test4;
        }
        location /test2 {
            return 200 "/test2";
        }
        location /test3 {
            return 200 "/test3";
        }
        location /test4 {
            return 200 "/test4";
        }

測試鏈接:http://10.0.0.2/test1 匹配到 location / {}后,被重寫為/test2,順序執(zhí)行再次被重寫為/test3,因為flag為last,所以不會繼續(xù)重寫為/test4,而是發(fā)起一次location匹配,匹配到location /test3{},所以最終返回結(jié)果為http200及/test3;

如果把location /{}中的last改為break,被重寫為/test3后,不再重寫為/test4,也不會發(fā)起location,最終沒有可匹配的資源,返回http404。

正則匹配 URL 的參數(shù)傳遞

小括號()之間匹配的內(nèi)容,可以在后面通過 下標(biāo) 來引用,如1表示引用第一個小括號匹配的內(nèi)容,$表示引用第二個小括號匹配的內(nèi)容。

location / {
           rewrite ^/(test1)/(test2)/(test3) /$2/$3;
           return 200 $2-$3;
        }

nginx 內(nèi)置全局變量

$args : 這個變量等于請求行中的參數(shù),同$query_string
$content_length : 請求頭中的Content-length字段。
$content_type : 請求頭中的Content-Type字段。
$document_root : 當(dāng)前請求在root指令中指定的值。
$host : 請求主機(jī)頭字段,否則為服務(wù)器名稱。
$http_user_agent : 客戶端agent信息
$http_cookie : 客戶端cookie信息
$limit_rate : 這個變量可以限制連接速率。
$request_method : 客戶端請求的動作,通常為GET或POST。
$remote_addr : 客戶端的IP地址。
$remote_port : 客戶端的端口。
$remote_user : 已經(jīng)經(jīng)過Auth Basic Module驗證的用戶名。
$request_filename : 當(dāng)前請求的文件路徑,由root或alias指令與URI請求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 請求使用的協(xié)議,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服務(wù)器地址,在完成一次系統(tǒng)調(diào)用后可以確定這個值。
$server_name : 服務(wù)器名稱。
$server_port : 請求到達(dá)服務(wù)器的端口號。
$request_uri : 包含請求參數(shù)的原始URI,不包含主機(jī)名,如:”/api/data?arg=abc”。
$uri : 不帶請求參數(shù)的當(dāng)前URI,$uri不包含主機(jī)名,如”/html/abc.html”。
$document_uri : 與$uri相同。

例子

請求文件或目錄不存在時重定向

if (!-e $request_filename) {
    rewrite ^(.*) http://www.baidu.com/ break;
}

用戶使用IE瀏覽器時重定向

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*) /nginx-ie/%1 break;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容