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

 

一. 簡單實例介紹
通常來講,apache配置好http和https後,若是想要作http強轉到https,須要設置url重定向規則,大體須要下面幾個步驟便可完成配置:php

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跳轉,則配置狀況會有所不一樣,以下:html

實現單個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) 示例一nginx

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,則是指 localhostgit

以上規則的意思是,若是訪問的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 兩個地址均可以訪問。github

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

所有網站根目錄爲   /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,內容以下:docker

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

或者內容爲:thinkphp

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的https證書免費申請和http->https跳轉配置                         

免費https證書能夠參考 (apache和nginx均可以使用,效果很強悍!):
https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc
https://my.oschina.net/jianhui1980/blog/1612469
http://www.javashuo.com/article/p-knasrepf-cr.html (推薦用這個連接,智能從apache配置中自動完成配置, 不須要指定網站根目錄)

配置記錄以下 (確保服務器的80和443端口在防火牆裏已經提早放行):

===========================================================================================
配置http:
  
[root@test-web-php extra]# cat httpd-vhosts.conf
<VirtualHost *:80>
    ServerAdmin webmaster@example.com
    DocumentRoot "/www/wwwroot/www.kevin.com/web"
    ServerName 0207917c.www.kevin.com
    ServerAlias www.kevin.com
    errorDocument 404 /404.html
    ErrorLog "/www/wwwlogs/www.kevin.com-error_log"
    CustomLog "/www/wwwlogs/www.kevin.com-access_log" combined
      
    #DENY FILES
     <Files ~ (\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)$>
       Order allow,deny
       Deny from all
    </Files>
      
    #PHP
    <FilesMatch \.php$>
            SetHandler "proxy:unix:/tmp/php-cgi-70.sock|fcgi://localhost"
    </FilesMatch>
      
    #PATH
    <Directory "/www/wwwroot/www.kevin.com/web">
        SetOutputFilter DEFLATE
        Options FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html index.htm default.php default.html default.htm
    </Directory>
</VirtualHost>
  
===========================================================================================
配置https:
  
[root@test-web-php extra]# cat httpd-ssl.conf
Listen 0.0.0.0:443
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder on
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
SSLPassPhraseDialog  builtin
SSLSessionCache        "shmcb:/www/server/apache/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300
   
<VirtualHost *:443>
    ServerAdmin webmaster@example.com
    DocumentRoot "/www/wwwroot/www.kevin.com/web"
    ServerName  www.kevin.com
    ServerAlias www.kevin.com
    errorDocument 404 /404.html
    SSLEngine on
    SSLCertificateFile "/home/ubuntu/www/ssl/cert.pem"
    SSLCertificateKeyFile "/home/ubuntu/www/ssl/key.pem"
    SSLCertificateChainFile "/home/ubuntu/www/ssl/fullchain.pem"
    ErrorLog "/www/wwwlogs/www.kevin.com-error_log"
    CustomLog "/www/wwwlogs/www.kevin.com-access_log" combined
      
    #DENY FILES
     <Files ~ (\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)$>
       Order allow,deny
       Deny from all
    </Files>
      
    #PHP
    <FilesMatch \.php$>
            SetHandler "proxy:unix:/tmp/php-cgi-70.sock|fcgi://localhost"
    </FilesMatch>
      
    #PATH
    <Directory "/www/wwwroot/www.kevin.com/web">
        SetOutputFilter DEFLATE
        Options FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html index.htm default.php default.html default.htm
    </Directory>
</VirtualHost>
  
===========================================================================================
配置http->https強轉
  
[root@test-web-php extra]# cat /www/wwwroot/www.kevin.com/web/.htaccess
<IfModule mod_rewrite.c>
    Options +FollowSymlinks -Multiviews
    RewriteEngine on
   
    # RewriteBase /
     RewriteCond %{SERVER_PORT} !^443$
     RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
   
    # if a directory or a file exists, use it directly
    RewriteCond %{REQUEST_FILENAME} !-f
   
    # otherwise forward it to index.php
    RewriteRule . index.php
</IfModule>
# General setting to properly handle LimeSurvey paths
# AcceptPathInfo on
  
===========================================================================================
證書路徑:
  
[root@test-web-php extra]# ll /home/ubuntu/www/ssl/
total 12
-rw-r--r-- 1 root root 1903 May 23 00:53 cert.pem
-rw-r--r-- 1 root root 3551 May 23 00:53 fullchain.pem
-rw------- 1 root root 1679 May 23 00:53 key.pem

二. 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]

3、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服務器,測試一下,就大功告成了!

4、分享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]

5、因爲有些例子是針對特殊路徑或特別狀況的,如下列出一些例子供參考:

目標 重寫設置 說明
規範化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
相關文章
相關標籤/搜索