Apache之Rewrite和RewriteRule規則梳理以及http強轉https的配置總結

散盡浮華發表於2018-08-31

 

一. 簡單例項介紹
一般來說,apache配置好http和https後,如果想要做http強轉到https,需要設定url重定向規則,大致需要下面幾個步驟即可完成配置:

1)在httpd.conf檔案裡使下面模組生效
[root@back ~]# cat /usr/local/apache/conf/httpd.conf
.....
LoadModule ssl_module modules/mod_ssl.so                      #開啟https功能模組
.....
LoadModule rewrite_module modules/mod_rewrite.so              #開啟重寫跳轉功能模組

2)httpd.conf配置檔案或者是在httpd-vhost.conf檔案裡修改
[root@back ~]# cat /usr/local/apache/conf/httpd.conf
.......
DocumentRoot "/data/vhosts"
<Directory "/data/vhosts">
    Options FollowSymLinks MultiViews Includes
    AllowOverride All                                     #AllowOverride None一定要修改為AllowOverride All!!
    Require all granted
</Directory>

3)在網站根目錄下面新增該檔案".htaccess"目錄訪問控制檔案,並新增如下內容:
RewriteEngine on          
RewriteBase /             
RewriteCond %{SERVER_PORT} !^443$    
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]    


含義是這樣的:為了讓使用者訪問傳統的http://轉到https://上來,用了一下rewrite規則:
第一句:啟動rewrite引擎
第三句:rewrite的條件是訪問的伺服器埠不是443埠
第四句:這是正規表示式,^是開頭,$是結束,/?表示有沒有/都可以(0或1個),(.*)是任何數量的任意字元
整句的意思是講:啟動rewrite模組,將所有訪問非443埠的域名請求,url地址內容不變,將http://變成https://。

上面的配置實現了將所有域名的http跳轉為https,如果只是針對某一個url的https跳轉,則配置情況會有所不同,如下:

實現單個url型別的https跳轉需求:
訪問http://bo.kevin.com/beijing/...... 強制跳轉到https://bo.kevin.com/beijing/......
配置如下:

[root@docker-test2 web]# cat .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} /beijing
RewriteRule ^(.*$) https://bobo.kevin.com/beijing/ [R,L]
</IfModule>

===========Apache下http跳轉至https的案例說明=============
1) 示例一

RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} !^/tz.php
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R]

%{SERVER_PORT}     說明訪問埠
%{REQUEST_URI}      比如如果url是 http://localhost/tz.php,則是指 /tz.php
%{SERVER_NAME}    比如如果url是 http://localhost/tz.php,則是指 localhost

以上規則的意思是,如果訪問的url的埠不是443,且訪問頁面不是tz.php,則應用RewriteRule這條規則。這樣便實現了:訪問了 http://localhost/index.php 或者 http://localhost/admin/index.php 等頁面的時候會自動跳轉到 https://localhost/index.php 或者 https://localhost/admin/index.php,但是訪問 http://localhost/tz.php 的時候就不會做任何跳轉,也就是說 http://localhost/tz.php 和 https://localhost/tz.php 兩個地址都可以訪問。

2) 示例二
.htaccess 在每一層獨立服務根目錄下都存在,例如

全部網站根目錄為   /var/www/html/.htaccess
士博部落格根目錄位   /var/www/html/shibo-wordpress/.htaccess
士博論壇根目錄位   /var/www/html/shibo-discuz/.htaccess
士博學習根目錄位   /var/www/html/shibo-study/.htaccess

HTTP 80 強制轉 HTTPS
全站採用https協議訪問,所以需要http重定向到https,只需要在.htaccess加入下面規則
在相應的網站根目錄新建 .htaccess

例如,在士博部落格的網站根目錄下,新建/var/www/html/shibo-wordpress/.htaccess,內容如下:

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

或者內容為:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*) https://%{SERVER_NAME}/$1 [R,L]

強制301重定向 HTTPS

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{SERVER_PORT} !^443$
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R=301,L]
</IfModule>

站點繫結多個域名
只允許kevin.con和www.kevin.com 跳轉

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^kevin.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www.kevin.com [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

高階用法 (可選)

RewriteEngine on

# 強制HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80

# 某些頁面強制
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

# 強制HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443

# 某些頁面強制
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

Apache mod_rewrite實現HTTP和HTTPS重定向跳轉

當你的站點使用了HTTPS之後,你可能會想把所有的HTTP請求(即埠80的請求),全部都重定向至HTTPS(即埠443)。這時候你可以用以下的方式來做到:(Apache mod_rewrite)把這段程式碼放在.htaccess檔案,即可實現HTTP到HTTPS的重定向。

 RewriteEngine On
 RewriteBase /
 RewriteCond %{SERVER_PORT} 80
 RewriteRule ^(.*)$ https://blog.shibo.com/$1 [R=301,L]
</IfModule>

而當你又想用回HTTP的時候,反過來就可以了:

<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteCond %{SERVER_PORT} 443
 RewriteRule ^(.*)$ https://blog.shibo.com/$1 [R=301,L]
</IfModule>

其中R=301表示Moved Permanently,即告訴搜尋引擎或者瀏覽器下去直接訪問後者的地址,如果只是試驗性地重定向,可以使用R=302(Found),臨時跳轉

VirtualHost 新增重定向
需要注意實測以上方法,對於下面需求場景,都無效!!下面專案場景:
1) 在我的根目錄下 /var/www/htmp/
2) 配置有多個網站,如士博部落格(/var/www/htmp/shibo-blog/)、士博論壇(/var/www/htmp/shibo-forum/)、士博學習(/var/www/htmp/shibo-study/)等
3) 對於士博部落格的http請求,全部定向到https部落格;對於士博論壇的http請求,全部定向到https論壇;

最後,解決方案是在 VirtualHost 節點裡,新增如下配置:

RewriteEngine on
RewriteCond   %{HTTPS} !=on
RewriteRule   ^(.*)  https://%{SERVER_NAME}$1 [L,R]

完整配置引數如下:

# blog
<VirtualHost *:80>
    ServerAdmin yanggang_2050@163.com
    DocumentRoot /var/www/html/wordpress
    ServerName blog.shibo.com
 
    RewriteEngine on
    RewriteCond   %{HTTPS} !=on
    RewriteRule   ^(.*)  https://%{SERVER_NAME}$1 [L,R]
 
    DirectoryIndex index.php
    ErrorLog /var/log/blog.shibo.com-error_log
    CustomLog /var/log/blog.shibo.com-access_log common
</VirtualHost>

3) 示例三

在啟用了https之後,還要保證之前的http埠可以開啟,http的80埠是有兩個網址的,所以這就導致需要把原來的帶www和不帶www的kevin.com域名同時指定一個https網址上面(https://kevin.com),需要做兩個Apache的301重定向,這個其實是很簡單的,最簡單的做法是直接在 .htaccess檔案中新增兩個301即可,如下所示:

rewritecond %{http_host} ^www.kevin.com [nc]  
RewriteRule ^(.*)?$ https://kevin.com/$1 [R=301,L]  
  
RewriteCond %{SERVER_PORT} !^443$  
RewriteRule ^(.*)?$ https://kevin.com/$1 [R=301,L]  

第一個 301 很自然就是帶 www 的跳轉到新的 https 上面了,而下面的301重定向則是判斷如果埠不是80的話,則進行重定向,這樣的話,帶www和不帶www的域名就一起跳轉到 https 一個網址上面了,當然這種全站做301的方法是比較暴力的,通常情況下我們只要把主域名做個301就可以了,我這裡是因為啟用了原來的兩個域名。

4) 示例四:一些其它的 Apache http 跳轉到 https 的方法

方法1

RewriteEngine On  
RewriteBase /  
RewriteCond %{SERVER_PORT} 80  
RewriteRule ^(.*)$ https://kevin.com/$1 [R=301,L]  

#這樣跳轉的好處是獨立IP主機也支援,訪問ip能自動跳轉到https

方法2

RewriteEngine on 
RewriteCond %{SERVER_PORT} !^443$ 
RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [R=301,L]

#整站跳轉

方法3

RewriteEngine on 
RewriteBase /yourfolder 
RewriteCond %{SERVER_PORT} !^443$ 
#RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [R=301,L] 
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

#以上至針對某個目錄跳轉, yourfolder就是目錄名

方法4

RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} /beijing
RewriteRule ^(.*$) https://test.kevin.com/beijing/ [R,L]

#針對url中的次級path路徑,比如上面的beijing,上面配置可以實現:
訪問http://test.kevin.com/beijing/....  跳轉到 https://test.kevin.com/beijing/.....

方法5

# 強制HTTPS方式訪問,對WWW或頂級域名不做跳轉。
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.kevin.com/$1 [L,R=301]

#強制HTTPS方式訪問,並自動將頂級域名跳轉到WWW。
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.kevin.com$ [NC]
RewriteRule ^(.*)$ https://www.kevin.com/$1 [L,R=301]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.kevin.com/$1 [L,R=301]

#強制HTTPS方式訪問,並自動將WWW跳轉到頂級域名。
RewriteEngine On
RewriteCond %{HTTP_HOST} !^kevin.com$ [NC]
RewriteRule ^(.*)$ https://kevin.com/$1 [L,R=301]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://kevin.com/$1 [L,R=301]

方法6

redirect 301 /你的網頁 https://你的主機+網頁

#針對某個網頁跳轉

比如:
redirect 301 /beijing.html https://www.kevin.com/beijing.html

方法7

下面是一個http跳轉https的配置
修改根目錄.htaccess檔案,內容配置如下:

<IfModule mod_rewrite.c>
 Options +FollowSymlinks
 RewriteEngine On

#thinkphp去掉index.php
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

 #http自動跳轉到https
 RewriteCond %{SERVER_PORT} !^443$

 #只有匹配對應的域名才會跳轉
 RewriteCond %{SERVER_NAME} ^hrsc.cc|www.hrsc.cc$
 RewriteRule (.*) https://%{SERVER_NAME}/$1 [R]

</IfModule>

二. Apache中 RewriteRule跳轉規則引數

Apache模組mod_rewrite提供了一個基於正規表示式分析器的重寫引擎來實時重寫URL請求。它支援每個完整規則可以擁有不限數量的子規則以及附加條件規則的靈活而且強大的URL操作機制。此URL操作可以依賴於各種測試,比如伺服器變數、環境變數、HTTP頭、時間標記,甚至各種格式的用於匹配URL組成部分的查詢資料庫。

mod_rewrite模組可以操作URL的所有部分(包括路徑資訊部分),在伺服器級的(httpd.conf)和目錄級的(.htaccess)配置都有效,還可以生成最終請求字串。此重寫操作的結果可以是內部子處理,也可以是外部請求的轉向,甚至還可以是內部代理處理。

以下重點介紹下RewriteRule 的規則以及引數說明。RewriteRule指令是重寫引擎的根本。此指令可以多次使用。每個指令定義一個簡單的重寫規則。這些規則的定義順序尤為重要——在執行時,規則是按這個順序逐一生效的

配置格式:
RewriteRule Pattern Substitution [flags]

1) Pattern是一個作用於當前URL的perl相容的正規表示式
"當前URL"是指該規則生效時刻的URL的值。它可能與被請求的URL截然不同,因為其他規則可能在此之前已經發生匹配並對它做了改動。

2) Substitution是當原始URL與Pattern相匹配時,用來替代(或替換)的字串。除了純文字,還可以包含:
-  對Pattern的反向引用($N)
-  對最後匹配的RewriteCond的反向引用(%N)
-  規則條件測試字串(%{VARNAME})中的伺服器變數
-  對映函式呼叫(${mapname:key|default})

3) [flags]標記作為RewriteRule指令的第三個引數,是一個包含以逗號分隔的下列標記的列表:

3.1) 'chain|C'(連結下一規則)
此標記使當前規則與下一個規則相連結。它產生這樣的效果:
如果一個規則被匹配,則繼續處理其後繼規則,也就是這個標記不起作用;
如果該規則不被匹配,則其後繼規則將被跳過。

比如:
在一個目錄級規則中執行一個外部重定向時,你可能需要刪除".www"(此處不應該出現".www")。
'cookie|CO=NAME:VAL:domain[:lifetime[:path]]'(設定cookie):在客戶端設定一個cookie。cookie的名稱是NAME,值是VAL。
domain是該cookie的域,比如'.apache.org',可選的lifetime是cookie的有效期(分鐘),可選的path是cookie的路徑。

3.2) 'env|E=VAR:VAL'(設定環境變數)
此標記將環境變數VAR的值設為VAL,VAL可以包含可擴充套件的正規表示式反向引用($N和%N)。此標記可以多次使用以設定多個變數。
這些變數可以在其後許多情況下被間接引用,通常是在XSSI(<!--#echo var="VAR"-->)或CGI($ENV{'VAR'})中,也可以在後繼的
RewriteCond指令的CondPattern引數中通過%{ENV:VAR}引用。使用它可以記住從URL中剝離的資訊。

3.3) 'forbidden|F'(強制禁止URL)
強制禁止當前URL,也就是立即反饋一個HTTP響應碼403(被禁止的)。使用這個標記,可以連結若干個RewriteConds來有條件地阻塞某些URL。

3.4) 'gone|G'(強制廢棄URL)
強制當前URL為已廢棄,也就是立即反饋一個HTTP響應碼410(已廢棄的)。使用這個標記,可以標明頁面已經被廢棄而不存在了。

3.5) 'handler|H=Content-handler'(強制指定內容處理器)
強自制定目標檔案的內容處理器為Content-handler。例如,用來模擬mod_alias模組的ScriptAlias指令,以強制對映資料夾內的所有檔案都
由"cgi-script"處理器處理。

3.6) 'last|L'(結尾規則)
立即停止重寫操作,並不再應用其他重寫規則。它對應於Perl中的last命令或C語言中的break命令。
這個標記用於阻止當前已被重寫的URL被後繼規則再次重寫。例如,使用它可以重寫根路徑的URL('/')為實際存在的URL(比如:'/e/www/')。

3.7) 'next|N'(從頭再來)
重新執行重寫操作(從第一個規則重新開始)。此時再次進行處理的URL已經不是原始的URL了,而是經最後一個重寫規則處理過的URL。
它對應於Perl中的next命令或C語言中的continue命令。此標記可以重新開始重寫操作(立即回到迴圈的開頭)。但是要小心,不要製造死迴圈!

3.8) 'nocase|NC'(忽略大小寫)
它使Pattern忽略大小寫,也就是在Pattern與當前URL匹配時,'A-Z'和'a-z'沒有區別。

3.9) 'noescape|NE'(在輸出中不對URI進行轉義)
此標記阻止mod_rewrite對重寫結果應用常規的URI轉義規則。 一般情況下,特殊字元('%', '$', ';'等)會被轉義為等值的十六進位制編碼('%25', '%24', '%3B'等)。
此標記可以阻止這樣的轉義,以允許百分號等符號出現在輸出中,比如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] ,可以使'/foo/zed轉向到一個安全的請求'/bar?arg=P1=zed'。

3.10) 'nosubreq|NS'(不對內部子請求進行處理)
在當前請求是一個內部子請求時,此標記強制重寫引擎跳過該重寫規則。比如,在mod_include試圖搜尋目錄預設檔案(index.xxx)時,Apache會在內部產生子請求。對於子請求,重寫規則不一定有用,而且如果整個規則集都起作用,它甚至可能會引發錯誤。所以,可以用這個標記來排除某些規則。
使用原則:如果你為URL新增了CGI指令碼字首,以強制它們由CGI指令碼處理,但對子請求處理的出錯率(或資源開銷)很高,在這種情況下,可使用這個標記。

3.11) 'proxy|P'(強制為代理)
此標記使替換成分被內部地強制作為代理請求傳送,並立即中斷重寫處理,然後把處理移交給mod_proxy模組。
你必須確保此替換串是一個能夠被mod_proxy處理的有效URI(比如以http://hostname開頭),否則將得到一個代理模組返回的錯誤。
使用這個標記,可以把某些遠端成分對映到本地伺服器域名空間,從而增強了ProxyPass指令的功能。
注意:要使用這個功能,必須已經啟用了mod_proxy模組。

3.12) 'passthrough|PT'(移交給下一個處理器)
此標記強制重寫引擎將內部request_rec結構中的uri欄位設定為filename欄位的值,這個小小的修改使得RewriteRule指令的輸出能夠被(從URI轉換到檔名的)Alias, ScriptAlias, Redirect等指令進行後續處理。

舉一個能說明其含義的例子:
如果要將/abc重寫為/def, 然後再使用mod_alias將/def轉換為/ghi,可以這樣:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi

如果省略了PT標記,雖然將uri=/abc/...重寫為filename=/def/...的部分運作正常,但是後續的mod_alias在試圖將URI轉換到檔名時會遭遇失效。
注意:如果需要混合使用多個將URI轉換到檔名的模組時,就必須使用這個標記。此處混合使用mod_alias和mod_rewrite就是個典型的例子。

3.13) 'qsappend|QSA'(追加查詢字串)
此標記強制重寫引擎在已有的替換字串中追加一個查詢字串,而不是簡單的替換。如果需要通過重寫規則在請求串中增加資訊,就可以使用這個標記。

3.14) 'redirect|R [=code]'(強制重定向)
若Substitution以http://thishost[:thisport]/(使新的URL成為一個URI)開頭,可以強制性執行一個外部重定向。如果沒有指定code,則產生一個HTTP響應碼302(臨時性移動)。如果需要使用在300-400範圍內的其他響應程式碼,只需在此指定即可(或使用下列符號名稱之一:temp(預設), permanent, seeother)。使用它可以把規範化的URL反饋給客戶端,如將"/~"重寫為"/u/",或始終對/u/user加上斜槓,等等。

注意:在使用這個標記時,必須確保該替換欄位是一個有效的URL。否則,它會指向一個無效的位置!並且要記住,此標記本身只是對URL加上http://thishost[:thisport]/字首,重寫操作仍然會繼續進行。通常,你還會希望停止重寫操作而立即重定向,那麼就還需要使用'L'標記。

3.15) 'skip|S=num'(跳過後繼規則)
此標記強制重寫引擎跳過當前匹配規則之後的num個規則。它可以模擬if-then-else結構:最後一個規則是then從句,而被跳過的skip=N個規則是else從句。注意:它和'chain|C'標記是不同的!

3.16)'type|T=MIME-type'(強制MIME型別)
強制目標檔案的MIME型別為MIME-type,可以用來基於某些特定條件強制設定內容型別。比如,下面的指令可以讓.php檔案在以.phps副檔名呼叫的情況下由mod_php按照PHP原始碼的MIME型別(application/x-httpd-php-source)顯示:RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]

===========RewriteRule跳轉設定案例===========
下列配置內容都寫到.htaccess檔案中,且 .htaccess檔案放到apache站點根目錄下.

1) 如果http://kevin.com/foo/bar不存在,則跳轉到http://other.kevin.com/foo/bar  (.htaccess檔案放在kevin.com域名的root根目錄下)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ http://other.kevin.com/$1 [R]

2)http://kevin.com/foo/bar的GET請求重定向到http://kevin.com/bar(或是將http://kevin.com/foo/bar.html請求重定向到http://kevin.com/bar.html)。用PHP程式處理POST請求,而不是試圖重定向一個帖子(這不太可能奏效)。 (.htaccess檔案放在kevin.com域名的root根目錄下):

RewriteEngine On
RewriteCond   %{REQUEST_METHOD}   GET
RewriteRule   ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$   /$1   [R,L,NS]
RewriteCond   %{REQUEST_METHOD}   POST
RewriteRule   ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$   /foo/show.php   [L,NS]

3) 用一個PHP程式/foo/show.php.處理對沒有副檔名的top-level.html檔案和檔案的所有請求.實現http://www.kevin.com/bobo跳轉到http://www.kevin.com/bobo.html  (.htaccess檔案放在www.kevin.com域名的root根目錄下):

RewriteRule   ^/?([^/]*\.html?|[^\./]*)[:;,\.]*$   /foo/show.php   [L,NS]

三、Apache Rewrite 規則詳解

1) Rewrite規則簡介:
Rewirte主要的功能就是實現URL的跳轉,它的正規表示式是基於Perl語言。可基於伺服器級的(httpd.conf)和目錄級的(.htaccess)兩種方式。如果要想用到rewrite模組,必須先安裝或載入rewrite模組。方法有兩種一種是編譯apache的時候就直接安裝rewrite模組,別一種是編譯apache時以DSO模式安裝apache,然後再利用原始碼和apxs來安裝rewrite模組。

基於伺服器級的(httpd.conf)有兩種方法:
一種是在httpd.conf的全域性下直接利用RewriteEngine on來開啟rewrite功能;
另一種是在區域性裡利用RewriteEngine on來開啟rewrite功能;

下面將會舉例說明,需要注意的是,必須在每個virtualhost裡用RewriteEngine on來開啟rewrite功能。否則virtualhost裡沒有RewriteEngine on, 它裡面的規則也不會生效。

基於目錄級的(.htaccess),要注意一點那就是必須開啟此目錄的FollowSymLinks屬性且在.htaccess裡要宣告RewriteEngine on。

2) 案例說明:

案例一
下面是在一個虛擬主機裡定義的規則。功能是把client請求的主機字首不是www.kevin.com和192.168.100.29都跳轉到主機字首為http://www.kevin.com,避免當使用者在位址列寫入http://kevin.com時不能以會員方式登入網站。

NameVirtualHost 192.168.100.8:80

ServerAdmin
DocumentRoot "/web/webapp"
ServerName www.kevin.com.cn
ServerName kevin.com.cn
RewriteEngine on 
RewriteCond   %{HTTP_HOST}   !^www.kevin.cn   [NC]   
RewriteCond   %{HTTP_HOST}   !^192.168.10.29   [NC]   
RewriteCond   %{HTTP_HOST}   !^$   
RewriteRule   ^/(.*)   http://www.kevin.cn/  [L]  

以上配置解釋:
RewriteEngine on      表示開啟rewirte功能
RewriteCond %{HTTP_HOST} !^www.kevin.com [NC]       表示宣告Client請求的主機中字首不是www.kevin.com,[NC]的意思是忽略大小寫
RewriteCond %{HTTP_HOST} !^192.168.100.29 [NC]       表示宣告Client請求的主機中字首不是192.168.100.29,[NC]的意思是忽略大小寫
RewriteCond %{HTTP_HOST} !^$       表示宣告Client請求的主機中字首不為空
RewriteRule ^/(.*) http://www.kevin.com/ [L]       表示如果Client請求的主機中的字首符合上述條件,則直接進行跳轉到http://www.kevin.com/,[L]意味著立即停止重寫操作,並不再應用其他重寫規則。這裡的.*是指匹配所有URL中不包含換行字元,()括號的功能是把所有的字元做一個標記,以便於後面的應用。$1就是引用前面裡的(.*)字元。

案例二
將輸入 test.kevin.com 的域名時跳轉到tech.kevin.com

listen 8080
NameVirtualHost 192.168.10.25:8080
ServerAdmin
DocumentRoot  "/usr/local/www/apache22/data1/"
ServerName  tech.kevin.com
RewriteEngine on
RewriteCond   %{HTTP_HOST}   ^test.kevin.com  [NC]
RewriteRule   ^/(.*)   tech.kevin.com  [L]

3) Apache mod_rewrite規則重寫的標誌一覽(上面其實已經介紹了)
3.1)  R[=code](force redirect) 強制外部重定向
強制在替代字串加上http://thishost[:thisport]/字首重定向到外部的URL.如果code不指定,將用預設的302 HTTP狀態碼。
3.2)  F(force URL to be forbidden)禁用URL,返回403HTTP狀態碼。
3.3)  G(force URL to be gone) 強制URL為GONE,返回410HTTP狀態碼。
3.4)  P(force proxy) 強制使用代理轉發。
3.5)  L(last rule) 表明當前規則是最後一條規則,停止分析以後規則的重寫。
3.6)  N(next round) 重新從第一條規則開始執行重寫過程。
3.7)  C(chained with next rule) 與下一條規則關聯
如果規則匹配則正常處理,該標誌無效,如果不匹配,那麼下面所有關聯的規則都跳過。
3.8)  T=MIME-type(force MIME type) 強制MIME型別
3.9)  NS (used only if no internal sub-request) 只用於不是內部子請求
3.10)  NC(no case) 不區分大小寫
3.11)  QSA(query string append) 追加請求字串
3.12)  NE(no URI escaping of output) 不再輸出轉義特殊字元
例如:

RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]         #能正確的將/foo/zoo轉換成/bar?arg=P1=zed

3.13)  PT(pass through to next handler) 傳遞給下一個處理
例如:

RewriteRule ^/abc(.*) /def$1 [PT]      #將會交給/def規則處理
lias /def /ghi 

3.14)  S=num(skip next rule(s)) 跳過num條規則
3.15)  E=VAR:VAL(set environment variable) 設定環境變數

4) Apache rewrite例子集合
在httpd中將一個域名轉發到另一個域名,新域名為www.kevin.com, 更加簡短好記。這時需要將原來的域名kevin.cn, 以及論壇所在地址kevin.com/forums/定向到新的域名,以便使用者可以找到,並且使原來的論壇 URL 繼續有效而不出現 404 未找到,比如原來的http://www.kevin.com/forums/f60.html, 讓它在新的域名下繼續有效,點選後轉發到http://bbs.kevin.com/f60.html, 這就需要用apache的Mod_rewrite功能來實現。
在.htaccess中新增下面的重定向規則:

RewriteEngine On
# Redirect webhosting-kevin.com/forums to bbs.kevin.com
RewriteCond   %{REQUEST_URI}   ^/forums/
RewriteRule    /forums/(.*)    http://bbs.kevin.com/$1   [R=permanent,L]
# Redirect webhosting-kevin.com to kevin.com
RewriteCond   %{REQUEST_URI}   !^/forums/
RewriteRule   /(.*)   http://www.kevin.com/$1   [R=permanent,L]

5) URL重定向

5.1) 案例一
訪問   http://www.kevin.com/xxx.php   重定向跳轉到   http://www.kevin.com/xxx/
訪問   http://yyy.kevin.com   重定向跳轉到   http://www.kevin.com/user.php?username=yyy

RewriteEngine On
RewriteCond   %{HTTP_HOST}   ^www.kevin.com
RewriteCond   %{REQUEST_URI}   !^user\.php$
RewriteCond   %{REQUEST_URI}   \.php$
RewriteRule    (.*)\.php$   http://www.kevin.com/$1/  [R]
RewriteCond   %{HTTP_HOST}   !^www.kevin.com
RewriteRule   ^(.+) %{HTTP_HOST}   [C]
RewriteRule   ^([^\.]+)\.kevin\.com   http://www.kevin.com/user.php?username=$1

5.2) 例子二
/type.php?typeid=*   重定向跳轉到   /type*.html
/type.php?typeid=*&page=*    重定向跳轉到   /type*page*.html

RewriteRule   ^/type([0-9]+).html$   /type.php?typeid=$1   [PT]
RewriteRule   ^/type([0-9]+)page([0-9]+).html$   /type.php?typeid=$1&page=$2   [PT]

6) 使用Apache的URL Rewrite配置多使用者虛擬伺服器
要實現這個功能,首先要在DNS伺服器上開啟域名的泛域名解析(自己做或者找域名服務商做)。
比如,我就把 *.kevin.com和 *.zzz.net全部解析到了我的這臺Linux Server上。然後,看一下我的Apache中關於*.kevin.com的虛擬主機的設定。

#*.com,*.kevin.net

ServerAdmin
DocumentRoot  /home/www/www.kevin.com
ServerName dns.kevin.com
ServerAlias dns.kevin.com kevin.com kevin.net *.kevin.com *.kevin.net
CustomLog /var/log/httpd/zzz/access_log.log" common
ErrorLog /var/log/httpd/zzz/error_log.log"
AllowOverride None
Order deny,allow
#AddDefaultCharset GB2312


RewriteEngine on
RewriteCond   %{HTTP_HOST}   ^[^.]+\.zzz\.(com|net)$
RewriteRule   ^(.+) %{HTTP_HOST}$1  [C]
RewriteRule   ^([^.]+)\.zzz\.(com|net)(.*)$   /home/www/www.kevin.com/sylvan$3?un=$1&%{QUERY_STRING}   [L]

在上面這段設定中,把*.kevin.net和*.kevin.com 的Document Root都設定到了/home/www/www.kevin.com,後面都配置了URL Rewrite規則。
RewriteEngine on      #開啟URL Rewrite功能
RewriteCond %{HTTP_HOST} ^[^.]+.zzz.(com|net)$     #匹配條件,如果使用者輸入的URL中主機名是類似 xxxx.kevin.com 或者 xxxx.kevin.net 就執行下面一句
RewriteRule ^(.+) %{HTTP_HOST}$1 [C]    #把使用者輸入完整的地址(GET方式的引數除外)作為引數傳給下一個規則,[C]是Chain串聯下一個規則的意思
RewriteRule ^([^.]+)\.zzz\.(com|net)(.*)$ /home/www/www.kevin.com/sylvan$3?un=$1&%{QUERY_STRING} [L]
# 最關鍵的是這一句,使用證則表示式解析使用者輸入的URL地址,把主機名中的使用者名稱資訊作為名為un的引數傳給/home/www/www.kevin.com目錄下的指令碼,並在後面跟上使用者輸入的GET方式的傳入引數。並指明這是最後一條規則([L]規則)。注意,在這一句中指明的重寫後的地址用的是伺服器上的絕對路徑,這是內部跳轉。如果使用http://xxxx這樣的URL格式,則被稱為外部跳轉。使用外部跳轉的話,瀏覽著的瀏覽器中的URL地址會改變成新的地址,而使用內部跳轉則瀏覽器中的地址不發生改變,看上去更像實際的二級域名虛擬伺服器。

這樣設定後,重啟Apache伺服器,測試一下,就大功告成了!

四、分享13個mod_rewrite 應用例項

1) 給子域名加www標記

RewriteCond   %{HTTP_HOST}   ^([a-z.]+)?example\.com$ [NC] 
RewriteCond   %{HTTP_HOST}   !^www\. [NC] 
RewriteRule   .?   http://www.%1example.com%{REQUEST_URI}   [R=301,L] 

這個規則抓取二級域名的%1變數,如果不是以www開始,那麼就加www,以前的域名以及{REQUEST_URI}會跟在其後。

2) 去掉域名中的www標記

RewriteCond   %{HTTP_HOST}   !^example\.com$   [NC] 
RewriteRule   .?   http://example.com%{REQUEST_URI}   [R=301,L]

3) 去掉www標記,但是儲存子域名

RewriteCond   %{HTTP_HOST}   ^www\.(([a-z0-9_]+\.)?example\.com)$   [NC] 
RewriteRule   .?   http://%1%{REQUEST_URI}   [R=301,L]

這裡,當匹配到1%變數以後,子域名才會在%2(內部原子)中抓取到,而我們需要的正是這個%1變數。

4) 防止圖片盜鏈
一些站長不擇手段的將你的圖片盜鏈在他們網站上,耗費你的頻寬。你可以加一下程式碼阻止這種行為。

RewriteCond   %{HTTP_REFERER}   !^$ 
RewriteCond    %{HTTP_REFERER}   !^http://(www\.)?example\.com/   [NC] 
RewriteRule   \.(gif|jpg|png)$   - [F] 

如果{HTTP_REFERER}值不為空,或者不是來自你自己的域名,這個規則用[F]FLAG阻止以gif|jpg|png 結尾的URL 
如果對這種盜鏈你是堅決鄙視的,你還可以改變圖片,讓訪問盜鏈網站的使用者知道該網站正在盜用你的圖片。

RewriteCond   %{HTTP_REFERER}   !^$ 
RewriteCond   %{HTTP_REFERER}   !^http://(www\.)?example\.com/.*$ [NC] 
RewriteRule   \.(gif|jpg|png)$   http://你的圖片地址   [R=301,L] 

除了阻止圖片盜鏈連結,以上規則將其盜鏈的圖片全部替換成了你設定的圖片。 
你還可以阻止特定域名盜鏈你的圖片:

RewriteCond   %{HTTP_REFERER}   !^http://(www\.)?leech_site\.com/   [NC] 
RewriteRule   \.(gif|jpg|png)$   - [F,L]

這個規則將阻止域名黑名單上所有的圖片連結請求。 
當然以上這些規則都是以{HTTP_REFERER}獲取域名為基礎的,如果你想改用成IP地址,用{REMOTE_ADDR}就可以了。

5) 如果檔案不存在重定向到404頁面
如果你的主機沒有提供404頁面重定向服務,那麼我們自己建立。

RewriteCond   %{REQUEST_FILENAME}   !-f 
RewriteCond   %{REQUEST_FILENAME}   !-d 
RewriteRule   .?   /404.php   [L] 

這裡-f匹配的是存在的檔名,-d匹配的存在的路徑名。這段程式碼在進行404重定向之前,會判斷你的檔名以及路徑名是否存在。你還可以在404頁面上加一個?url=$1引數:

RewriteRule ^/?(.*)$ /404.php?url=$1 [L]

這樣,你的404頁面就可以做一些其他的事情,例如預設信心,發一個郵件提醒,加一個搜尋,等等。

6) 重新命名目錄

如果你想在網站上重新命名目錄,試試這個:

RewriteRule   ^/?old_directory/([a-z/.]+)$   new_directory/$1   [R=301,L]

在規則裡我新增了一個“.”(注意不是代表得所有字元,前面有轉義符)來匹配檔案的字尾名。

7) 將.html字尾名轉換成.php

前提是.html檔案能繼續訪問的情況下,更新你的網站連結。 

RewriteRule   ^/?([a-z/]+)\.html$   $1.php   [L]

這不是一個網頁重定向,所以訪問者是不可見的。讓他作為一個永久重定向(可見的),將FLAG修改[R=301,L]。

8) 建立無檔案字尾名連結

如果你想使你的PHP網站的連結更加簡潔易記-或者隱藏檔案的字尾名,試試這個: 

RewriteRule   ^/?([a-z]+)$   $1.php   [L]

如果網站混有PHP以及HTML檔案,你可以用RewriteCond先判斷該字尾的檔案是否存在,然後進行替換

RewriteCond   %{REQUEST_FILENAME}.php   -f 
RewriteRule   ^/?([a-zA-Z0-9]+)$   $1.php   [L] 
RewriteCond   %{REQUEST_FILENAME}.html   -f 
RewriteRule   ^/?([a-zA-Z0-9]+)$   $1.html   [L]

如果檔案是以.php為字尾,這條規則將被執行。

9) 檢查查詢變數裡的特定引數

如果在URL裡面有一個特殊的引數,你可用RewriteCond鑑別其是否存在

RewriteCond   %{QUERY_STRING}   !uniquekey= 
RewriteRule   ^/?script_that_requires_uniquekey\.php$   other_script.php   [QSA,L]

以上規則將檢查{QUERY_STRING}裡面的uniquekey引數是否存在,如果{REQUEST_URI}值為script_that_requires_uniquekey,將會定向到新的URL。 

10)刪除查詢變數

Apache的mod_rewrite模組會自動辨識查詢變數,除非你做了以下改動: 

a).分配一個新的查詢引數(你可以用[QSA,L]FLAG儲存最初的查詢變數) 

b).在檔名後面加一個“?”(比如index.php?)。符號“?”不會在瀏覽器的位址列裡顯示。

11) 用新的格式展示當前URI 

如果這就是我們當前正在執行的URLs:/index.php?id=nnnn。我們非常希望將其更改成/nnnn並且讓搜尋引擎以新格式展現。首先,我們為了讓搜尋引擎更新成新的,得將舊的URLs重定向到新的格式,但是,我們還得保證以前的index.php照樣能夠執行。

實現以上功能,訣竅就在於在查詢變數中加了一個訪問者看不到的標記符“marker”。我們只將查詢變數中沒有出現“marker”標記的連結進行重定向,然後將原有的連結替換成新的格式,並且通過[QSA]FLAG在已有的引數加一個“marker”標記。以下為實現的方式: 

RewriteCond   %{QUERY_STRING}   !marker 
RewriteCond   %{QUERY_STRING}   id=([-a-zA-Z0-9_+]+) 
RewriteRule   ^/?index\.php$   %1?   [R=301,L] 
RewriteRule   ^/?([-a-zA-Z0-9_+]+)$   index.php?marker&id=$1  [L]

這裡,原先的URL:http://www.example.com/index.php?id=nnnn,不包含marker,所以被第一個規則永久重定向到http://www.example.com/nnnn,第二個規則將http://www.example.com/nnnn反定向到http://www.example.com/index.php?marker&id=nnnn,並且加了marker以及id=nnnn兩個變數,最後mod_rewrite就開始進行處理過程。

第二次匹配,marker被匹配,所以忽略第一條規則,這裡有一個“.”字元會出現在http://www.example.com/index.php?marker&id=nnnn中,所以第二條規則也會被忽略,這樣我們就完成了。

注意,這個解決方案要求Apache的一些擴充套件功能,所以如果你的網站放於在共享主機中會遇到很多障礙。

12) 保證安全服務啟用

Apache可以用兩種方法辨別你是否開啟了安全服務,分別引用{HTTPS}和{SERVER_PORT}變數: 

RewriteCond   %{REQUEST_URI}   ^secure_page\.php$ 
RewriteCond   %{HTTPS}   !on 
RewriteRule   ^/?(secure_page\.php)$   https://www.kevin.com/$1 [R=301,L]

以上規則測試{REQUEST_URI}值是否等於我們的安全頁程式碼,並且{HTTPS}不等於on。如果這兩個條件同時滿足,請求將被重定向到安全服務URI.另外你可用{SERVER_PORT}做同樣的測試,443是常用的安全服務埠 

RewriteCond    %{REQUEST_URI}    ^secure_page\.php$ 
RewriteCond    %{SERVER_PORT}    !^443$ 
RewriteRule    ^/?(secure_page\.php)$    https://www.kevin.com/$1   [R=301,L]

13) 在特定的頁面上強制執行安全服務 

遇到同一個伺服器根目錄下分別有一個安全服務域名和一個非安全服務域名,所以你就需要用RewriteCond 判斷安全服務埠是否佔用,並且只將以下列表的頁面要求為安全服務: 

RewriteCond    %{SERVER_PORT}    !^443$ 
RewriteRule    ^/?(page1|page2|page3|page4|page5)$    https://www.kevin.com/%1  [R=301,L] 

以下是怎樣將沒有設定成安全服務的頁面返回到80埠:

RewriteCond    %{ SERVER_PORT }   ^443$ 
RewriteRule   !^/?(page6|page7|page8|page9)$   zzz.com%{REQUEST_URI} [R=301,L]

五、由於有些例子是針對特殊路徑或特別情況的,以下列出一些例子供參考:

目標 重寫設定 說明
規範化URL RewriteRule   ^/~([^/]+)/?(.*)   /u/$1/$2 [R] 將/~user重寫為/u/user的形式
  RewriteRule   ^/([uge])/([^/]+)$   /$1/$2/ [R] 將/u/user末尾漏掉的/補上
     
規範化HostName RewriteCond   %{HTTP_HOST}   !^fully\.qualified\.domain\.name   [NC] 域名不合格
  RewriteCond   %{HTTP_HOST}   !^$ 不空
  RewriteCond   %{SERVER_PORT}   !^80$ 不是80埠
  RewriteRule   ^/(.*)   http://fully.qualified.domain.name:%{SERVER_PORT}/$1   [L,R] 重寫
  RewriteCond   %{HTTP_HOST}   !^fully\.qualified\.domain\.name   [NC]  
  RewriteCond   %{HTTP_HOST}   !^$  
  RewriteRule   ^/(.*)   http://fully.qualified.domain.name/$1   [L,R]  
     
URL根目錄轉移 RewriteEngine on  
  RewriteRule   ^/$   /e/www/ [R] 從/移到/e/www/
     
末尾目錄補斜線 RewriteEngine on  
(目錄範圍內) RewriteBase   /~quux/  
  RewriteRule   ^foo$   foo/   [R] /~quux/foo是一個目錄,補/
     
  RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteCond   %{REQUEST_FILENAME}   -d 如果請檔名是個目錄
  RewriteRule   ^(.+[^/])$   $1/ [R] URL末尾不是斜線時補上
     
Web叢集 RewriteEngine on  
  RewriteMap   user-to-host   txt:/path/to/map.user-to-host 使用者-伺服器對映
  RewriteMap   group-to-host   txt:/path/to/map.group-to-host 組-伺服器對映
  RewriteMap   entity-to-host   txt:/path/to/map.entity-to-host 實體-伺服器對映
  RewriteRule   ^/u/([^/]+)/?(.*)   http://${user-to-host:$1|server0}/u/$1/$2 使用者均衡
  RewriteRule   ^/g/([^/]+)/?(.*)   http://${group-to-host:$1|server0}/g/$1/$2 組均衡
  RewriteRule   ^/e/([^/]+)/?(.*)   http://${entity-to-host:$1|server0}/e/$1/$2 實體均衡
  RewriteRule   ^/([uge])/([^/]+)/?$   /$1/$2/.www/  
  RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\  
     
URL根目錄搬遷 RewriteEngine on  
  RewriteRule   ^/~(.+)   http://newserver/~$1   [R,L] 到其它伺服器
     
所使用者名稱首字母分 RewriteEngine on  
  RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)   /home/$2/$1/.www$3 內一層括號為$2
     
NCSA imagemap移 RewriteEngine on  
植為mod_imap RewriteRule   ^/cgi-bin/imagemap(.*)   $1   [PT]  
     
多目錄查詢資源 RewriteEngine on  
  # first try to find it in custom/...  
  RewriteCond   /your/docroot/dir1/%{REQUEST_FILENAME}   -f  
  RewriteRule   ^(.+) /your/docroot/dir1/$1   [L]  
  # second try to find it in pub/...  
  RewriteCond   /your/docroot/dir2/%{REQUEST_FILENAME}   -f  
  RewriteRule   ^(.+)   /your/docroot/dir2/$1   [L]  
  # else go on for other Alias or ScriptAlias directives,  
  RewriteRule   ^(.+)   - [PT]  
     
據URL設定環境變數 RewriteEngine on  
  RewriteRule   ^(.*)/S=([^/]+)/(.*)   $1/$3 [E=STATUS:$2]  
     
虛擬主機 RewriteEngine on  
  RewriteCond   %{HTTP_HOST}   ^www\.[^.]+\.host\.com$ 基於使用者名稱
  RewriteRule   ^(.+)   %{HTTP_HOST}$1   [C]  
  RewriteRule   ^www\.([^.]+)\.host\.com(.*)   /home/$1$2  
     
內外人有別 RewriteEngine on  
  RewriteCond   %{REMOTE_HOST}   !^.+\.ourdomain\.com$ 基於遠端主機
  RewriteRule   ^(/~.+)   http://www.somewhere.com/$1   [R,L]  
     
錯誤重定向 RewriteEngine on  
  RewriteCond   /your/docroot/%{REQUEST_FILENAME}   !-f 不是regular檔案
  RewriteRule   ^(.+)   http://webserverB.dom/$1  
     
程式處理特殊協議 RewriteRule   ^xredirect:(.+)   /path/to/nph-xredirect.cgi/$1 \ Xredirect協議
  [T=application/x-httpd-cgi,L]  
     
最近映象下載 RewriteEngine on  
  RewriteMap   multiplex   txt:/path/to/map.cxan 頂級域名與最近ftp伺服器對映
  RewriteRule   ^/CxAN/(.*)   %{REMOTE_HOST}::$1 [C]  
  RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$   ${multiplex:$1|ftp.default.dom}$2   [R,L] 據頂級域名不同提供不同的FTP伺服器
     
基於時間重寫 RewriteEngine on  
  RewriteCond   %{TIME_HOUR}%{TIME_MIN}   >0700  
  RewriteCond   %{TIME_HOUR}%{TIME_MIN}   <1900  
  RewriteRule   ^foo\.html$   foo.day.html 白天為早晚7點間
  RewriteRule   ^foo\.html$   foo.night.html 其餘為夜間
     
向前相容副檔名 RewriteEngine on  
  RewriteBase /~quux/  
  # parse out basename, but remember the fact  
  RewriteRule   ^(.*)\.html$   $1   [C,E=WasHTML:yes]  
  # rewrite to document.phtml if exists  
  RewriteCond   %{REQUEST_FILENAME}.phtml -f 如果存在$1.phtml則重寫
  RewriteRule   ^(.*)$   $1.phtml   [S=1]  
  # else reverse the previous basename cutout  
  RewriteCond   %{ENV:WasHTML}   ^yes$ 如果不存在$1.phtml,則保持不變
  RewriteRule   ^(.*)$   $1.html  
     
檔案改名(目錄級) RewriteEngine on 內部重寫
  RewriteBase   /~quux/  
  RewriteRule   ^foo\.html$   bar.html  
     
  RewriteEngine on 重定向由客戶端再次提交
  RewriteBase   /~quux/  
  RewriteRule   ^foo\.html$   bar.html   [R]  
     
據瀏覽器型別重寫 RewriteCond   %{HTTP_USER_AGENT}   ^Mozilla/3.*  
  RewriteRule   ^foo\.html$ foo.NS.html   [L]  
  RewriteCond   %HTTP_USER_AGENT}   ^Lynx/.* [OR]  
  RewriteCond   %{HTTP_USER_AGENT}   ^Mozilla/[12].*  
  RewriteRule   ^foo\.html$   foo.20.html [L]  
  RewriteRule   ^foo\.html$   foo.32.html [L]  
     
動態映象遠端資源 RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteRule   ^hotsheet/(.*)$   http://www.tstimpreso.com/hotsheet/$1   [P] 利用了代理模組
     
  RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteRule   ^usa-news\.html$   http://www.quux-corp.com/news/index.html [P]  
     
反向動態映象 RewriteEngine on  
  RewriteCond   /mirror/of/remotesite/$1   -U  
  RewriteRule   ^http://www\.remotesite\.com/(.*)$   /mirror/of/remotesite/$1  
     
負載均衡 RewriteEngine on 利用代理實現round-robin效果
  RewriteMap   lb   prg:/path/to/lb.pl  
  RewriteRule   ^/(.+)$   ${lb:$1} [P,L]  
     
  #!/path/to/perl  
  $| = 1;  
  $name = "www"; # the hostname base  
  $first = 1; # the first server (not 0 here, because 0 is myself)  
  $last = 5; # the last server in the round-robin  
  $domain = "foo.dom"; # the domainname  
  $cnt = 0;  
  while () {  
  $cnt = (($cnt+1) % ($last+1-$first));  
  $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);  
  print "http://$server/$_";  
  }  
  ##EOF##  
     
靜態頁面變指令碼 RewriteEngine on  
  RewriteBase   /~quux/  
  RewriteRule   ^foo\.html$   foo.cgi   [T=application/x-httpd-cgi]  
     
阻擊機器人 RewriteCond   %{HTTP_USER_AGENT}   ^NameOfBadRobot.*  
  RewriteCond   %{REMOTE_ADDR}   ^123\.45\.67\.[8-9]$  
  RewriteRule   ^/~quux/foo/arc/.+   - [F]  
     
阻止盜連你的圖片 RewriteCond   %{HTTP_REFERER}   !^$  
  RewriteCond   %{HTTP_REFERER}   !^http://www.quux-corp.de/~quux/.*$   [NC] 自己的連線可不能被阻止
  RewriteRule   .*\.gif$   - [F]  
     
  RewriteCond   %{HTTP_REFERER}   !^$  
  RewriteCond   %{HTTP_REFERER}   !.*/foo-with-gif\.html$  
  RewriteRule   ^inlined-in-foo\.gif$   - [F]  
     
拒絕某些主機訪問 RewriteEngine on  
  RewriteMap   hosts-deny   txt:/path/to/hosts.deny  
  RewriteCond   ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}   !=NOT-FOUND   [OR]  
  RewriteCond   ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}   !=NOT-FOUND  
  RewriteRule   ^/.*   - [F]  
     
使用者授權 RewriteCond   %{REMOTE_IDENT}@%{REMOTE_HOST}   !^friend1@client1.quux-corp\.com$  
  RewriteCond   %{REMOTE_IDENT}@%{REMOTE_HOST}   !^friend2@client2.quux-corp\.com$  
  RewriteCond   %{REMOTE_IDENT}@%{REMOTE_HOST}   !^friend3@client3.quux-corp\.com$  
  RewriteRule   ^/~quux/only-for-friends/   - [F]  
     
外部重寫程式模板 RewriteEngine on  
  RewriteMap   quux-map   prg:/path/to/map.quux.pl  
  RewriteRule   ^/~quux/(.*)$   /~quux/${quux-map:$1}  
     
  #!/path/to/perl  
  $| = 1;  
  while (<>) {  
  s|^foo/|bar/|;  
  print $_;  
  }  
     
搜尋引擎友好 RewriteRule   ^/products$   /content.php  
  RewriteRule   ^/products/([0-9]+)$   /content.php?id=$1  
  RewriteRule   ^/products/([0-9]+),([ad]*),([0-9]{0,3}),([0-9]*),([0-9]*$)   /marso/content.php?id=$1&sort=$2&order=$3&start=$4  

==============================================================================
針對apache的route路由轉發設定,注意下面幾個配置點

1)修改httpd.conf主配置檔案
[root@kevin01 ~]# cat /usr/local/apache/conf/httpd.conf
........
LoadModule rewrite_module modules/mod_rewrite.so        #開啟重寫轉發功能模組

DocumentRoot "/data/www/public"                                     
<Directory "/data/www/public">                                          # apache的站點根目錄注意修改
    Options FollowSymLinks MultiViews Includes
    AllowOverride All                                                             #要將預設的None改為All
    Require all granted
</Directory>

DirectoryIndex index.html index.php                                    #網站首頁預設讀出index.php和index.html

2)配置vhosts虛擬主機
[root@kevin01 ~]# cat /usr/local/apache/conf/extra/kevin.conf 
<VirtualHost *:80>
   ServerName www.kevin-inc.com
   DocumentRoot /data/www/public
   DirectoryIndex index.php index.html

   ErrorLog "/var/log/httpd/www.kevin.com-error_log"
   CustomLog "/var/log/httpd/www.kevin.com-access_log" common

</VirtualHost>

3)配置站點根目錄/data/www/public路徑下的.htaccess檔案
[root@kevin01 ~]# cat /data/www/public/.htaccess 
<IfModule mod_rewrite.c>
  Options +FollowSymlinks -Multiviews
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

4)重啟apache服務
[root@kevin01 ~]# /usr/local/apache/bin/httpd -t
Syntax OK
[root@kevin01 ~]# /usr/local/apache/bin/httpd -k restart

5)另外要注意apache站點根目錄下的許可權,一定要修改為apache啟動使用者的許可權
[root@kevin01 ~]# ps -ef|grep apache
root      3631     1  0 Oct14 ?        00:00:27 /usr/local/apache/bin/httpd
daemon   13770  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd
daemon   13775  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd

[root@kevin01 ~]# chown -R daemon.daemon /data/www/public


==================================================
如果apache是http強轉為https關係的route路由轉發的配置,基本配置注意點如下:

1)配置httpd.conf主配置檔案
[root@kevin01 ~]# cat /usr/local/apache/conf/httpd.conf

LoadModule ssl_module modules/mod_ssl.so                        #開啟https訪問的功能模組

LoadModule rewrite_module modules/mod_rewrite.so            #開啟重寫跳轉功能模組

DocumentRoot "/data/www/public"
<Directory "/data/www/public">
    Options FollowSymLinks MultiViews Includes
    AllowOverride All
    Require all granted
</Directory>

DirectoryIndex index.html index.php

2)配置vhosts虛擬主機
[root@kevin01 ~]# cat /usr/local/apache/conf/extra/kevin.conf 
<VirtualHost *:80>
   ServerName www.kevin.com
   DocumentRoot /data/www/public
   DirectoryIndex index.php index.html

   ErrorLog "/var/log/httpd/www.kevin.com-error_log"
   CustomLog "/var/log/httpd/www.kevin.com-access_log" common

</VirtualHost>

[root@kevin01 ~]# cat /usr/local/apache/conf/extra/httpd-ssl.conf
Listen 443
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder on 
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
SSLPassPhraseDialog  builtin
SSLSessionCache        "shmcb:/usr/local/apache/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300
 
<VirtualHost *:443>
DocumentRoot "/data/www/public"
ServerName www.kevin.com
DirectoryIndex index.php index.html

SSLEngine on
SSLCertificateFile "/usr/local/apache/conf/ssl/ssl.kevin.com.crt"
SSLCertificateKeyFile "/usr/local/apache/conf/ssl/ssl.kevin.com.key"
     ErrorLog "logs/www.kevin.com-https-error_log"
     CustomLog "logs/www.kevin.com-https-access_log" combined
</VirtualHost>

[root@kevin01 ~]# ll /usr/local/apache/conf/ssl/
total 8
-rw-rw-r-- 1 root root 4085 Apr  8  2018 ssl.kevin.com.crt
-rw-rw-r-- 1 root root 1706 Apr  8  2018 ssl.kevin.com.key

3)配置站點根目錄/data/www/public路徑下的.htaccess檔案(包括http強轉到https的配置)
[root@kevin01 ~]# cat /data/www/public/.htaccess 
<IfModule mod_rewrite.c>
  Options +FollowSymlinks -Multiviews
  RewriteEngine On

 RewriteCond %{SERVER_PORT} !^443$
 RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

4)重啟apache服務
[root@kevin01 ~]# /usr/local/apache/bin/httpd -t
Syntax OK
[root@kevin01 ~]# /usr/local/apache/bin/httpd -k restart

5)另外要注意apache站點根目錄下的許可權,一定要修改為apache啟動使用者的許可權
[root@kevin01 ~]# ps -ef|grep apache
root      3631     1  0 Oct14 ?        00:00:27 /usr/local/apache/bin/httpd
daemon   13770  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd
daemon   13775  3631  0 18:13 ?        00:00:00 /usr/local/apache/bin/httpd

[root@kevin01 ~]# chown -R daemon.daemon /data/www/public

相關文章