nginx rewrite規則


1.rewrite的介紹

nginx的rewrite規則就是使用正則匹配請求的url,然后根據定義的規則進行重寫和改變,需ngx_http_rewrite_module模塊來支持url重寫功能,該模塊是標准模塊,默認已經安裝。

url和uri的區別:

URI:Universal Resource Identifier ,通用資源標識符,用於對網絡中的各種資源進行標識,由存放資源的主機名、片段標志符和相對的URI三部分組成。存放資源的主機名一般由傳輸協議(Scheme)、主機和資源路徑三部分組成;片段標識符指向資源內容的具體元素、相對URI表示資源在主機上的相對路徑。一般格式為:Scheme://[用戶名][:密碼]@主機名[:端口號][/資源路徑]

URL:Uniform Resource Location,統一資源定位符,是用於在Internet中描述資源的字符串,是URI的子集,主要包括傳輸協議(Scheme)、主機(IP、端口號或者域名)和資源集體地址(目錄或文件名)等三部分,一般格式為:scheme://主機名[:端口號]/[資源路徑]

2.rewrite涉及的指令

執行順序:

1.執行server塊的rewrite指令(這里的塊指的是server關鍵字后{}包圍的區域,其它xx塊類似)
2.執行location匹配
3.執行選定的location中的rewrite指令
如果其中某步URI被重寫,則重新循環執行1-3,直到找到真實存在的文件

如果循環超過10次,則返回500 Internal Server Error錯誤

1)if指令

    語法:if(condition){...}

默認值:無

作用域:server,location

對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執行。

if條件(conditon)可以是如下任何內容:

 

一個變量名;false如果這個變量是空字符串或者以0開始的字符串;

使用= ,!= 比較的一個變量和字符串,true/false

使用~, ~*與正則表達式匹配的變量,如果這個正則表達式中包含右花括號}或者分號;則必須給整個正則表達式加引號

使用-f ,!-f 檢查一個文件是否存在

使用-d, !-d 檢查一個目錄是否存在

使用-e ,!-e 檢查一個文件、目錄、符號鏈接是否存在

使用-x , !-x 檢查一個文件是否可執行

if指令實例

 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;

 }

2)return指令

用於完成對請求的處理,直接給客戶端返回狀態碼,改指令后所有的nginx配置都是無效的,

語法:return code;

return code URL;

return URL;

默認值:無

作用域:server,location,if

3)set指令

 

語法:set variable value;

默認值:none

作用域:server,location,if

定義一個變量並賦值,值可以是文本,變量或者文本變量混合體。

 

4)uninitialized_variable_warn指令

語法:uninitialized_variable_warn on | off;

默認值:uninitialized_variable_warn on

作用域:http,server,location,if

控制是否輸出為初始化的變量到日志

5)rewrite指令

該指令通過正則來改變url,可以同時存在一個或者多個指令

語法:rewrite regex replacement [flag];

默認值:無

作用域:server,location,if

regex :用於匹配uri的正則表達式。使用括號()標記要截取的內容

replacement 匹配成功后用於替換uri中被截取內容的字符串,默認情況下,如果該字符串是由http://或者https://開頭的,則不會繼續向下對uri進行其他處理,而是直接將重寫后的uri返回給客戶端

flag 用來設置rewrite對uri的處理行為,常用的有

    last 停止處理后續rewrite指令集,然后對當前重寫的新URI在rewrite指令集上重新查找。

break 停止處理后續rewrite指令集,並不在重新查找,但是當前location內剩余非rewrite語句和location外的的非rewrite語句可以執行。

redirect 如果replacement不是以http:// 或https://開始,返回302臨時重定向

permant 返回301永久重定向

 補充:last和break標記的區別在於,last標記在本條rewrite規則執行完后,會對其所在的server { … } 標簽重新發起請求,而break標記則在本條規則匹配完成后,停止匹配,不再做后續的匹配。另外有些時候必須使用last,比如在使用alias指令時,而 使用proxy_pass指令時則必須使用break。

注意:rewrite 規則優先級要高於location,在nginx配置文件中,nginx會先用rewrite來處理url,最后再用處理后的url匹配location

6)常用的變量

$args : #這個變量等於請求行中的參數,同$query_string

$content_length : 請求頭中的Content-length字段。

$content_type : 請求頭中的Content-Type字段。

$document_root : 當前請求在root指令中指定的值。

$host : 請求主機頭字段,否則為服務器名稱。

$http_user_agent : 客戶端agent信息

$http_cookie : 客戶端cookie信息

$limit_rate : 這個變量可以限制連接速率。

$request_method : 客戶端請求的動作,通常為GET或POST。

$remote_addr : 客戶端的IP地址。

$remote_port : 客戶端的端口。

$remote_user : 已經經過Auth Basic Module驗證的用戶名。

$request_filename : 當前請求的文件路徑,由root或alias指令與URI請求生成。

$scheme : HTTP方法(如http,https)。

$server_protocol : 請求使用的協議,通常是HTTP/1.0或HTTP/1.1。

$server_addr : 服務器地址,在完成一次系統調用后可以確定這個值。

$server_name : 服務器名稱。

$server_port : 請求到達服務器的端口號。

$request_uri : 包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。

$uri : 不帶請求參數的當前URI,$uri不包含主機名,如”/foo/bar.html”。

$document_uri : 與$uri相同。

7)常用正則:

. : 匹配除換行符以外的任意字符

? : 重復0次或1次

+ : 重復1次或更多次

* : 重復0次或更多次

\d :匹配數字

^ : 匹配字符串的開始

$ : 匹配字符串的介紹

{n} : 重復n次

{n,} : 重復n次或更多次

[c] : 匹配單個字符c

[a-z] : 匹配a-z小寫字母的任意一個

小括號()之間匹配的內容,可以在后面通過$1來引用,$2表示的是前面第二個()里的內容。正則里面容易讓人困惑的是\轉義特殊字符。

 

配置案例

 

1. 在URL結尾添加斜杠

在虛擬主機中這么添加一條改寫規則:

  1. rewrite ^(.*[^/])$ $1/ permanent;
 

 

2. 刪除URL結尾的斜杠

在虛擬主機中這么添加一條改寫規則:

 

  1. rewrite ^/(.*)/$ /$1 permanent;
 

 


免責聲明!

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



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