nginx中rewrite用法
一、rewrite規則
rewrite功能就是使用nginx提供的全局變量或自己設置的變量,結合正則表達式和標誌位實現url重寫以及重定向。
rewrite只能放在server{},location{},if{}中,並且只能對域名後邊的除去傳遞的參數外的字符串起作用,例如http://seanlook.com/a/we/index.PHP?id=1&u=str 只對/a/we/index.php重寫。語法rewrite regex replacement [flag];
如果相對域名或參數字符串起作用,可以使用全局變量匹配,也可以使用proxy_pass反向代理。
二、rewrite與 location區別及執行過程
表明看rewrite和location功能有點像,都能實現跳轉,主要區別在於rewrite是在同一域名內更改獲取資源的路徑,而location是對一類路徑做控制訪問或反向代理,可以proxy_pass到其他機器。很多情況下rewrite也會寫在location裏,它們的執行順序是:
1、執行server塊的rewrite指令
2、執行location匹配
3、執行選定的location中的rewrite指令
提示:如果其中某步URI被重寫,則重新循環執行1-3,直到找到真實存在的文件;循環超過10次,則返回500 Internal Server Error錯誤。
三、rewrite語法格式及參數說明
1、rewrite語法格式
rewrite語法格式:rewrite regex replacement [flag];
rewrite | <regex> | <replacement> | [flag]; |
關鍵字 | 正則 | 替代內容 | flag標記 |
flag標記說明:
last #本條規則匹配完成後,繼續向下匹配新的location URI規則
break #本條規則匹配完成即終止,不再匹配後面的任何規則
redirect #返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址
permanent #返回301永久重定向,瀏覽器地址欄會顯示跳轉後的URL地址
例1:rewrite ^/(.*) http://www.test.com/$1 permanent;
例1說明:
rewrite為固定關鍵字,表示開始進行rewrite匹配規則
regex部分是 ^/(.*) ,這是一個正則表達式,匹配完整的域名和後面的路徑地址
replacement部分是http://www.test.com/$1,$1是取自regex部分()裏的內容。匹配成功後跳轉到的URL。
flag部分 permanent表示永久301重定向標記,即跳轉到新的 http://www.test.com/$1 地址上
2、rewrite 常用正則表達式說明
字符 | 描述 |
. | 匹配除換行符以外的任意字符 |
? | 匹配前面的字符零次或一次 |
+ | 匹配前面的字符一次或多次 |
* | 匹配前面的字符0次或多次 |
\d | 匹配一個數字字符。等價於[0-9] |
\ | 將後面接著的字符標記為一個特殊字符或一個原義字符或一個向後引用。如“\n”匹配一個換行符,而“\$”則匹配“$” |
^ | 匹配字符串的開始 |
$ | 匹配字符串的結尾 |
{n} | 匹配前面的字符n次 |
{n,} | 匹配前面的字符n次或更多次 |
[c] | 匹配單個字符c |
[a-z] | 匹配a-z小寫字母的任意一個 |
小括號()之間匹配的內容,可以在後面通過$1來引用,$2表示的是前面第二個()裏的內容。正則裏面容易讓人困惑的是\轉義特殊字符。
3、if指令和可使用的全局變量
(1)if判斷指令語法
if ( 條件判斷 )
{ rewrite ... }
對給定的條件進行判斷。如果為真,大括號內的rewrite指令將被執行,if條件可以是如下任何內容:當表達式只是一個變量時,如果值為空或任何以0開頭的字符串都會當做false
=或!= | 直接比較變量和內容 |
~ | 區分大小寫正則表達式匹配 |
~* | 不區分大小寫的正則表達式匹配 |
!~ | 區分大小寫的正則表達式不匹配 |
-f和!-f | 用來判斷文件是否存在 |
-d和!-d | 用來判斷目錄是否存在 |
-e和!-e | 用來判斷文件或目錄是否存在 |
-x和!-x | 用來判斷文件是否可執行 |
if指令語法實例
#如果UA包含"MSIE",rewrite請求到/msid/目錄下
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
#如果cookie匹配正則,設置變量$id等於正則引用部分
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
#如果提交方法為POST,則返回狀態405(Method not allowed)。return不能返回301,302
if ($request_method = POST) {
return 405;
}
#限速,$slow可以通過 set 指令設置
if ($slow) {
limit_rate 10k;
}
#如果請求的文件名不存在,則反向代理到localhost 。這裏的break也是停止rewrite檢查
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
}
#如果query string中包含"post=140",永久重定向到example.com
if ($args ~ post=140){
rewrite ^ http://example.com/ permanent;
}
#防盜鏈
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
}
}
(2)if判斷可使用的全局變量
變量名稱 | 變量說明 |
$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相同 |
例:
http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php
nginx中rewrite用法