RewriteCond與RewriteRule用法

admin發表於2018-07-19

Rewrite重寫任務基本上都是由RewriteCond和RewriteRule兩個命令配合完成。

首先看一段簡單程式碼:

[Shell] 純文字檢視 複製程式碼
RewriteBase /
RewriteCond %{http_host} ^softwhy.com$ [NC]
RewriteRule ^(.*)$ http://www.softwhy.com/$1 [R=301]

下面對上述程式碼做一下分析:

(1).RewriteBase /規定根目錄為基準路徑,具體參閱.htaccess RewriteBase用法一章節。

(2).RewriteCond規定重寫的條件,如果條件成立,那麼將會執行RewriteRule所規定的重寫規則。

具體程式碼細節,後面會做介紹,它實現不帶www的URL跳轉到帶有www的URL,比如:

[Shell] 純文字檢視 複製程式碼
softwhy.com/article-451-1.html
# 跳轉到如下連結
www.softwhy.com/article-451-1.html

一.RewriteCond命令:

它用來定義重寫規則執行的條件。

語法結構:

[Shell] 純文字檢視 複製程式碼
RewriteCond String Pattern [flags]

定義一個條件,當String所規定的內容與Pattern規則匹配時,才會執行RewriteRule規定重寫。

引數解析:

1.String:純文字的字串,除了包含普通的字元外,還可以包括下列的可擴充套件結構:

(1).$N:RewriteRule後向引用。$N引用緊跟在RewriteCond之後的RewriteRule中Pattern的小括號中的規則在當前URL中匹配的內容。N是0 <= N <= 9之間的整數。

(2).%N:RewriteCond後向引用 。%N引用最後一個RewriteCond的Pattern中的小括號中的規則在當前URL中匹配的內容。N是0 <= N <= 9之間的整數。

2.Pattern:應用於當前例項TestString的正規表示式 ,還可以包括以下擴充套件:

(1).!:表示TestString不與當前正則匹配;格式是!CondPattern。

(2).>: 將condPattern作為普通字串與String比較,String大於Pattern為真;格式是>Pattern。

(3).=:將condPattern作為普通字串與String比較,String與Pattern相同時為真;格式是=Pattern。

(4).-d:將String當作一個目錄名,檢查它是否存在以及是否是一個目錄;格式是-d。

(5).-f:將String當作一個檔名,檢查它是否存在以及是否是一個檔案;格式是-f。

(6).-s:將String當作一個檔名,檢查它是否存在以及是否是一個長度大於0的檔案;格式是-s。

(7).-l: 將String當作一個檔名,檢查它是否存在以及是否是一個 symbolic link;格式是-l。

(8).-F:檢查String是否是一個合法的檔案,而且通過伺服器範圍內的當前設定的訪問控制進行訪問。檢查通過一個內部subrequest完成的, 因此需要謹慎使用,以防止降低伺服器的效能。

(9).-U:檢查String是否是一個合法的URL,而且通過伺服器範圍內的當前設定的訪問控制進行訪問。檢查通過一個內部subrequest完成的, 因此需要謹慎使用,以防止降低伺服器的效能。

3.[flags]:多個標誌之間用逗號分隔。

(1).NC:表示不區分大小寫。

(2).OR:預設的情況下,二個條件之間是AND的關係,用這個標誌將關係改為OR。

二.RewriteRule命令:

它用來規定當RewriteCond條件滿足時要執行的規則。

語法結構:

[Shell] 純文字檢視 複製程式碼
RewriteRule Pattern Substitution [flags]

引數解析:

1.Pattern:作用於當前URL的正規表示式;此url不包含協議、域名和查詢字串部分。

2.Substitution:當RewriteCond滿足時,用來替換原始URL指定內容的字串,還可以包括以下擴充套件:

(1).$N:RewriteRule後向引用。$N引用緊跟在RewriteCond之後的RewriteRule中Pattern的小括號中的規則在當前URL中匹配的內容。N是0 <= N <= 9之間的整數。

(2).%N:RewriteCond後向引用 。%N引用最後一個RewriteCond的Pattern中的小括號中的規則在當前URL中匹配的內容。N是0 <= N <= 9之間的整數。

3.[flags]:多個標誌之間用逗號分隔,下面是常見的一些flag:

(1).R:表示重定性,[R=301]表示301重定向,預設是302重定向。

(2).F:強制當前URL為被禁止的,即,立即反饋一個HTTP響應程式碼403(被禁止的)。

(3).G:強制當前URL為已廢棄的,即,立即反饋一個HTTP響應程式碼410(已廢棄的)。

(4).L:立即停止重寫操作,並不再應用其他重寫規則。 

(5).N:重新執行重寫操作(從第一個規則重新開始). 這時再次進行處理的URL已經不是原始的URL了,而是經最後一個重寫規則處理的URL。

(6).C:此標記使當前規則與下一個(其本身又可以與其後繼規則相連結的, 並可以如此反覆的)規則相連結。 它產生這樣一個效果: 如果一個規則被匹配,通常會繼續處理其後繼規則, 即,這個標記不起作用;如果規則不能被匹配,則其後繼的連結的規則會被忽略。

(7).NC:忽略大小寫。

(8).QSA:此標記強制重寫引擎在已有的替換串中追加一個請求串,而不是簡單的替換。

程式碼例項:

[Shell] 純文字檢視 複製程式碼
RewriteCond %{http_host} ^softwhy.com$ [NC]
RewriteRule ^(.*)$ www.softwhy.com/$1 [R=301]

程式碼解析如下:

(1).RewriteCond用來規定執行後面重寫的條件。

(2).%{http_host}是一個伺服器變數,可以獲取訪問的域名,如果域名是"softwhy.com",新增成立。

(3).RewriteRule規定當RewriteCond條件成立索要執行的重寫規則。

(4).^(.*)$獲取URL除去協議、域名和查詢字串部分,比如softwhy.com/forum.php?mod=viewthread&tid=1,只獲取forum.php部分,域名和查詢部分不會被獲取,如果要獲取可以參閱RewriteRule QSA用法一章節。

(5).$1表示^(.*)$小括號所匹配的內容,$2表示第二個小括號所匹配的內容,以此類推。

(6).[R=301]表示原始網址重定向為後來重寫的網址。

(7).用softwhy.com/forum.php?mod=viewthread&tid=1訪問,softwhy.com/forum.php被www.softwhy.com/forum.php替換,最終是以www.softwhy.com/forum.php?mod=viewthread&tid=1訪問頁面。

[Shell] 純文字檢視 複製程式碼
RewriteCond %{HTTP_HOST} ^(.+)\.google\.com$   
RewriteRule ^/([\w]+)/([\d]+)$ /service/detail\.html\?id=$1&date=$2&c=%1 [L]

程式碼分析如下:

(1).%{HTTP_HOST}獲取域名。

(2).^(.+)\.google\.com$表示任何以google.com為根域名的域名。

(3).^/([\w]+)/([\d]+)$獲取訪問url兩個斜線之間的部分,比如a/b/x.php,那麼將會獲取a/b。

(4).$1獲取^/([\w]+)/([\d]+)$第一個小括號匹配的內容。

(5).$2獲取^/([\w]+)/([\d]+)$第二個小括號匹配的內容。

(6).%1獲取^(.+)\.google\.com$第一個小括號匹配的內容。

[Shell] 純文字檢視 複製程式碼
RewriteRule forum.php?mod=viewthread&tid=100 article-2094-1.html [R=301]

本意是,連結(www.)softwhy.comforum.php?mod=viewthread&tid=100跳轉到(www.)softwhy.article-2094-1.html,但是結果卻非常讓人失望,最後結果如下:

[Shell] 純文字檢視 複製程式碼
(www.)softwhy.article-2094-1.html??mod=viewthread&tid=100

如果Substitution沒有查詢字串部分,那麼它附加原來URL查詢字串部分。

程式碼修改如下:

[Shell] 純文字檢視 複製程式碼
RewriteRule forum.php?mod=viewthread&tid=100 article-2094-1.html? [R=301]

再後面新增一個問號即可。

相關文章