6、Nginx的Rewrite規則與實例

6.1 什麼是Nginx的Rewrite規則

Rewrite主要的功能就是實現URI的重寫,Nginx的Rewrite規則採用PCRE(Perl Compatible  Regular  Expressions)Perl 兼容正則表達式的語法進行規則匹配,若是您須要Nginx的Rewrite功能,在編輯Nginx以前,需要編譯安裝PCRE庫。html

正則表達式(Regular Expression)在計算機科學中,是指一個用來描述或匹配一系列符合某個句法規則的字符串的單個字符串。最初的正則表達式出現於理論計算機科學的自動控制理論和形式化語言理論中。在這些領域中有對計算(自動控制)的模型和對形式化語言描述與分類的研究。20世紀40年代,Warren McCulloch與Walter Pitts將神經系統中的神經元描述成小而簡單的自動控制元。20世紀50年代,數學家斯蒂芬·科爾·克萊尼稱之爲正則集合的數學符號來描述此模型。肯·湯普遜將此符號系統引入編輯器QED,而後是UNIX上的編輯器ed,並最終引入grep。自此,正則表達式被普遍適用於各類Unix或相似UNIX的工具,例如Perl。正則表達式

經過Rewrite規則,能夠實現規範的URL、根據變量來作URL轉向及選擇配置。例如,一些使用MVC框架的程序只有一個入口,能夠經過Rewrite來實現。一些動態URL地址須要假裝成靜態HTML,便於搜索引擎抓取,也須要Rewrite來處理。一些因爲目錄結構、域名變化的舊URL,須要跳轉到新的URL上,也能夠經過Rewrite來處理。瀏覽器

6.2 Nginx Rewrite規則相關指令

Nginx Rewrite規則相關指令有if、rewrite、set、return、break等,其中rewrite是最關鍵的指令。一個簡單的Nginx Rewrite規則語法以下:緩存

rewrite ^/b/(.*)\.html /play.jsp?video=$1 break;

若是加上if語句,示例以下:bash

if  (!-f  $request_filename)
{rewrite ^/img/(.*)$  /site/$host/images/$1 last;
}

6.2.1 break指令

語法:break

默認值:none

使用環境:server,location ,if

該指令的做用是完成當前的規則集,不在處理rewrite指令。服務器

示例以下:cookie

if($slow){
limit_rate  10k;
break;
}

6.2.2 if 指令

語法:if(condition){…….}
默認值:none
使用環境:server,location

該指令用於檢查一個條件是否符合,若是條件符合,則執行大括號內的語句。if指令不支持嵌套,不支持多個條件&&和||處理。框架

如下信息能夠被定爲條件:dom

(1)變量名,錯誤的值包括:空字符串「」,或者任何以0開始的字符串。jsp

(2)變量比較可使用「=」和「!=」運算符

(3)正則表達式模式匹配可使用「~」和「~*」符號;

(4)「~」符號表示區分大小寫字母的匹配

(5)「~*」符號表示不區分大小寫字母的匹配

(6)「!~」和「!~*」符號的做用恰好和「~」、「!~*」相反,表示不匹配

(7)「-f」和「~-f」用來判斷文件是否存在

(8)「-d」和「!-d」用來判斷目錄是否存在;

(9)「-e」和「!-e」用來判斷文件或目錄是否存在

(10)「-x」和「!-x」用來判斷文件是否可執行。

下面是實例代碼:

if  ($http_user_agnet ~ MSIE){
rewrite ^(.*)$ /msie/$1 break;
}
if  ($http_cookie ~* 「id=([^;] +)(?:;|$)」){
set $id $1;
}
if ($request_method = POST){return 405;
}
if  (! –f $request_filename){break;
proxy_pass  http://127.0.0.1;
}
if   ($slow){
limit_rate  10k;
}
if($invalid_referer){
return 403;
}

6.2.3 return 指令

語法:return code
默認值:none
使用環境:server、location、if

該指令用於結束規則的執行並返回狀態碼給客戶端。狀態碼可使用這些值:204,400,402~406,408,410,411,413,416及500~504.此外,非標準狀態碼444將以不發送任何Header頭的方式結束鏈接。

示例,若是訪問的URL以「.sh」和「.bash」結尾,則返回狀態碼403:

location ~ .*\.(sh|bash)?$
{
return  403;
}

下面咱們來詳細介紹return指令支持的狀態碼。

204 No Content:服務器成功處理了請求,但無須返回任何實體內容,而且但願返回更新了的元信息。響應可能經過實體頭部的形式,返回新的或更新後的元信息。若是存在這些頭部信息,則應當與所請求的變量相呼應。

若是客戶端是瀏覽器,那麼用戶瀏覽器應保留髮送了該請求的頁面,而不產生任何文檔視圖上的變化,即便按照規範新的或更新後的元信息,也應當被應用到用戶瀏覽器活動視圖中的文檔。

400 Bad Request:因爲包含語法錯誤,當前請求沒法被服務器理解。

402 Payment Required:該狀態碼是爲了未來可能的需求而預留的

403 Forbidden:服務器已經理解請求,可是拒絕執行。與401不一樣的是,身份驗證並不能提供任何幫助,並且這個請求也不該該被重複提交。若是這不是一個HEAD請求,並且服務器但願可以講清楚爲什麼請求不能被執行,就應該在實體內描述拒絕的緣由。固然服務器也能夠返回一個404響應,假如它不但願讓客戶端得到任何信息。

404 Not Found:請求失敗,請求所但願獲得的資源未在服務器上發現。

405 Method Not  Allowed:請求行中指定的請求方法不能被用於請求相應的資源。該響應必須返回一個Allow頭信息,用以表示出當前資源可以接受的請求方法的列表。

406 Not Acceptable:請求的資源的內容特性沒法知足請求頭中的條件,於是沒法生成響應實體。

408 Request TimeOut:請求超時。客戶端沒有在服務器預備等待的時間內完成一個請求的發送。

410 Gone:被請求的資源在服務器上已經再也不可用,並且沒有任何已知的轉發地址。這樣的情況應當被認爲是永久性的。若是可能,擁有鏈接編輯功能的客戶端應當在得到用戶許可後刪除全部指向這個地址的引用。若是服務器不知道或沒法肯定這個情況是不是永久的,就應該使用404狀態碼。除非額外說明,不然這個響應是可緩存的.

411 Length Required:服務器拒絕在沒有定義Content-Length頭的狀況下接受請求。在添加了代表請求消息體長度的有效Content-Length頭以後,客戶端能夠再次提交該請求。

413  Request Entity Too Large:服務器拒絕處理當前請求,由於該請求提交的實體數據大小超過了服務器願意或可以處理的範圍。此種狀況下,服務器能夠關閉鏈接以避免客戶端繼續發送此請求。若是這個情況是臨時的,服務器應當返回一個Retry-After的響應頭,以告知客戶端能夠在多少時間之後從新嘗試。

500  Internal  Server  Error:服務器遇到了一個不曾預料的情況,致使了它沒法完成對請求的處理。通常來講,這個問題都會在服務器的程序碼出錯時出現。

501 Not Implemented:服務器不支持當前請求所須要的某個功能。當服務器沒法識別請求的方法,而且沒法支持其對任何資源的請求時。

502 Bad Gateway:做爲網關或代理工做的服務器嘗試執行請求時,從上游服務器接收到無效的響應。

503 Service Unavailable:因爲臨時的服務器維護或過載,服務器當前沒法處理請求。這個情況是臨時的,而且將在一段時間之後恢復。若是可以預計延遲時間,那麼響應中能夠包含一個Retry-After頭用以標明這個延遲時間。若是沒有給出這個retry-after信息,那麼客戶端應當處理500響應的方式處理它。

注意:503狀態碼的存在並不意味着服務器在過載時候必須使用它。某些服務器只不過是但願拒絕客戶端的鏈接。

504 Gateway TimeOut:做爲網關或代理工做的服務器嘗試執行請求時,未能及時從上游服務器(URI)標識出的服務器,例如HTTP、FTP、LDAP或輔助服務器(例如DNS)收到響應。

注意:某些代理服務器在DNS查詢超時時會返回400或500錯誤。

6.2.4 rewrite 指令

語法:rewrite regex  replacement flag
默認值:none
使用環境:server,location,if

該指令根據表達式來重定向URI,或者修改字符串。指令根據配置文件中的順序來執行。

注意重寫表達式只對相對路徑有效。若是你想配對主機名你應該使用If語句,代碼以下:

if  ($host ~* www\.(.*)){
set $host_without_www $1;
rewrite ^(.*)$  http://$host_without_www$1 permanent ;#$1 contains ‘/foo’,not ‘www.mydomain.com/foo’
}

若是替換串以Http://開頭,將會採用301或302跳轉進行URL重定向。

rewrite指令的最後一項參數爲flag標記,支持的flag標記爲:

last:至關於Apache裏的[L]標記,表示完成rewrite;

break:本條規則匹配完成後,終止匹配,不在匹配後面的規則;

redirect:返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址

permanent:返回301永久重定向,瀏覽器地址欄會顯示跳轉後的URL地址。

在以上的標記中,last和break用來實現URI重寫,瀏覽器地址欄的URL地址不變,但在服務器端訪問的路徑發生了變化。Redirect和Permanent用來實現URL跳轉,瀏覽器地址欄會顯示跳轉後的URL地址。

last和break標記的實現功能相似,但兩者之間有細微的差異,使用alias指令時必須用last標記,使用proxy_pass指令時要使用break標記。last標記在本條rewrite規則執行完畢後,會對其所在server{……}標籤從新發起請求,而break標記則在本條規則匹配完成後,終止匹配,不在匹配後面的規則。例如如下這段規則,就必須使用break標記,使用last標記會致使死循環。實例:

if ($host ~* ^www\.gyic\.(.*?)$)
       {
       rewrite ^/(.*)$ http://www.gyic.com:9007/reserve last;
       }

6.2.5 set 指令

語法:set variable value
默認值:none
使用環境:Server,location,if

該指令用於定義一個變量,並給變量賦值。變量的值能夠爲文本、變量及文本的變量的聯合。實例以下:

set  $varname  ‘hello’
相關文章
相關標籤/搜索