APACHE REWRITE規則(內部重定向、外部重定向)

前陣子某天,一同事讓我幫忙看一下某內部服務器的域名跳轉的配置,原本這兩年好像沒作Web服務器方面東西了,不過鑑於曾經在互聯網行業工做過,仍是略懂Apache配置,也想順便玩一下。最後的配置仍是比價簡單的,也實現了他所需的功能。今天有點空閒時間,想寫篇博客總結一些apache rewrite的配置語法和實例(源於網絡資料),以便從此快速查閱。php

我最後其實就在httpd.conf文件寫了以下幾行配置就將域名中以「otc-team」開頭的URL重定向爲「http://otcteam.mycompany.com/」下面的對應URL。css

 

1html

2web

3正則表達式

RewriteEngine onexpress

RewriteCond %{HTTP_HOST} ^otc-team [NC]apache

RewriteRule ^(.*)  http://otcteam.mycompany.com/$1 [L]api

 

1. 一些基礎知識的介紹:
The mod_rewrite module uses a rule-based rewriting engine, based on a PCRE regular-expression parser, to rewrite requested URLs on the fly. By default, mod_rewrite maps a URL to a filesystem path. However, it can also be used to redirect one URL to another URL, or to invoke an internal proxy fetch.
mod_rewrite provides a flexible and powerful way to manipulate URLs using an unlimited number of rules. Each rule can have an unlimited number of attached rule conditions, to allow you to rewrite URL based on server variables, environment variables, HTTP headers, or time stamps.
mod_rewrite operates on the full URL path, including the path-info section. A rewrite rule can be invoked in httpd.conf or in .htaccess. The path generated by a rewrite rule can include a query string, or can lead to internal sub-processing, external request redirection, or internal proxy throughput.
簡單解釋一下內部重定向和外部重定向吧。內部重定向,是指域名並不發生變化,只是將某個URL映射到了文件系統中的另外一個路徑。外部重定向,是指URL已經法發生變化(在瀏覽器中顯示看到的域名也跟着變化了),從一個URL映射到了另外一個URL(能夠是不一樣主機的,固然也能夠是同一主機上的)。
PCRE(Perl Compatible Regular Expressions)是與Perl5.x兼容的正則表達式,使用這種正則表達式的著名軟件項目有Apache、PHP、KDE、Safari等。瀏覽器

重寫規則的做用範圍,有以下三種:
1) 可使用在Apache主配置文件httpd.conf中
2) 可使用在httpd.conf裏定義的虛擬主機配置中
3) 可使用在基本目錄的跨越配置文件.htaccess中
首先,apache在編譯時將mod_rewrite編譯爲模塊,而後在Apache的配置文件中加載它:
LoadModule rewrite_module modules/mod_rewrite.so
其次,這三種方式,都須要在寫規則前,用「RewriteEngine on」指令來打開rewrite功能。
假如你對你的的網站內容所在的服務器沒有管理員權限,或者你的網站放在ISP的服務器上託管等等條件下,你沒法改寫主配置文件,然而你能夠對你的WEB站點內容所在的目錄有寫權限,則你能夠設置本身的.htaccess文件。 (本博客站點就有設置.htaccess文件作rewrite。)對文件.htaccess所做的任何改動不須要重啓動Apache. 不過,值得注意的是,須要肯定主配置文件中對你的網站所在的目錄定義了下面的內容:
Options Indexes FollowSymLinks
AllowOverride all
不然你的.htaccess文件配置不會工做。

2. Apache mod_rewrite規則重寫的標誌一覽服務器

1) R[=code](force redirect) 強制外部重定向
強制在替代字符串加上http://thishost[:thisport]/前綴重定向到外部的URL.若是code不指定,將用缺省的302 HTTP狀態碼。
2) F(force URL to be forbidden)禁用URL,返回403HTTP狀態碼。
3) G(force URL to be gone) 強制URL爲GONE,返回410HTTP狀態碼。
4) P(force proxy) 強制使用代理轉發。
5) L(last rule) 代表當前規則是最後一條規則,中止分析之後規則的重寫。
6) N(next round) 從新從第一條規則開始運行重寫過程。
7) C(chained with next rule) 與下一條規則關聯
若是規則匹配則正常處理,該標誌無效,若是不匹配,那麼下面全部關聯的規則都跳過。
8.) T=MIME-type(force MIME type) 強制MIME類型
9) NS (used only if no internal sub-request) 只用於不是內部子請求
10) NC(no case) 不區分大小寫
11) QSA(query string append) 追加請求字符串
12) NE(no URI escaping of output) 不在輸出轉義特殊字符
例如:RewriteRule /foo/(.*) /bar?arg=P1%3d$1 [R,NE] #將能正確的將/foo/zoo轉換成/bar?arg=P1=zoo
13) PT(pass through to next handler) 傳遞給下一個處理
例如:
RewriteRule ^/abc(.*) /def$1 [PT] # 將會交給/def規則處理
Alias /def /ghi
14) S=num(skip next rule(s)) 跳過num條規則
15) E=VAR:VAL(set environment variable) 設置環境變量

另外,P是代理模式轉發,必須用url全稱,而且要保證modProxy打開,也就是下面httpd.conf中的以下兩個指令:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
若是對應proxy模塊沒加載,則會出現403禁止頁面。

3. 一些有用的實際rewrite例子
例1.下面是在一個虛擬主機裏定義的規則。功能是把client請求的主機前綴不是www.smilejay.com和173.192.169.119都跳轉到主機前綴爲http://www.smilejay.com,避免相同內容的網頁有多個指向的域名,如http://smilejay.com

 

1

2

3

4

5

6

7

8

9

10

    NameVirtualHost 173.192.169.119:80

    ServerAdmin smile665(AT)gmail.com

    DocumentRoot "/web"

    ServerName smilejay.com

 

    RewriteEngine on #打開rewirte功能

    RewriteCond %{HTTP_HOST} !^www.smilejay.com [NC] #聲明Client請求的主機中前綴不是www.smilejay.com,其中 [NC] 的意思是忽略大小寫

    RewriteCond %{HTTP_HOST} !^173.192.169.119 [NC] #聲明Client請求的主機中前綴不是70.40.213.183,其中 [NC] 的意思是忽略大小寫

    RewriteCond %{HTTP_HOST} !^$ #聲明Client請求的主機中前綴不爲空

    RewriteRule ^(.*) http://www.smilejay.com/ [L] #含義是若是Client請求的主機中的前綴符合上述條件,則直接進行跳轉到http://www.smilejay.com/,[L]意味着當即中止重寫操做,並再也不應用其餘重寫規則。這裏的.*是指匹配全部URL中的任意字符,()括號的功能是把全部的字符作一個標記,以便於後面用$1這樣的變量來引用,就是引用前面裏的(.*)字符。

 

例2. 將輸入 en.smilejay.com 的域名時跳轉到www.smilejay.com

 

1

2

3

    RewriteEngine on

    RewriteCond %{HTTP_HOST} ^en.smilejay.com [NC]

    RewriteRule ^(.*) http://www.smilejay.com/ [L]

 

例3. 賽卡軟件近期更換了域名,新域名爲www.sicasoft.com, 更加簡短好記。這時須要將原來的域名ss.kiya.cn, 以及論壇所在地址ss.kiya.cn/bbs/定向到新的域名,以便用戶能夠找到,而且使原來的論壇 URL 繼續有效而不出現 404 未找到,好比原來的http://ss.kiya.cn/bbs/tread-60.html, 讓它在新的域名下繼續有效,點擊後轉發到http://bbs.sicasoft.com/tread-60.html,而其餘網頁,如原先的http://ss.kiya.cn/purchase不會到二級域名bbs.sicasoft.com/purchase上,而是到www.sicasoft.com/purchase
按照這樣的要求重定向規則應該這樣寫:

 

1

2

3

4

5

    RewriteEngine On

    RewriteCond %{REQUEST_URI} ^/bbs/

    RewriteRule ^bbs/(.*) http://bbs.sicasoft.com/$1 [R=permanent,L]

    RewriteCond %{REQUEST_URI} !^/bbs/

    RewriteRule ^(.*) http://www.sicasoft.com/$1 [R=permanent,L]

 

例4: 同時達到下面兩個要求:
1.用http://www.zzz.com/xxx.php 來訪問 http://www.zzz.com/xxx/
2.用http://yyy.zzz.com 來訪問 http://www.zzz.com/user.php?username=yyy 的功能

 

1

2

3

4

5

6

7

8

    RewriteEngine On

    RewriteCond %{HTTP_HOST} ^www.zzz.com

    RewriteCond %{REQUEST_URI} !^user.php$

    RewriteCond %{REQUEST_URI} .php$

    RewriteRule (.*).php$ http://www.zzz.com/$1/ [R]

    RewriteCond %{HTTP_HOST} !^www.zzz.com

    RewriteRule ^(.+) %{HTTP_HOST} [C]

    RewriteRule ^([^.]+).zzz.com http://www.zzz.com/user.php?username=$1

 

例5:實現以下URL的rewrite:
/type*.html 被重定向爲 /type.php?typeid=*
/type*page*.html 被重定向爲 /type.php?typeid=*&page=*

 

1

2

    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服務器上打開域名的泛域名解析(本身作或者找域名服務商作)。好比,我就把 *.kiya.us和 *.kiya.cn所有解析到了個人IP地址70.40.213.183上。而後,看一下個人Apache中關於*.kiya.us的虛擬主機的設定。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

    ServerAdmin webmaster@kiya.us

    DocumentRoot /home/www/www.kiya.us

    ServerName dns.kiya.us

    ServerAlias dns.kiya.us kiya.us *.kiya.us

    CustomLog /var/log/httpd/osa/access_log.log」 common

    ErrorLog /var/log/httpd/osa/error_log.log」

    AllowOverride None

    Order deny,allow

 

    RewriteEngine on

    RewriteCond %{HTTP_HOST} ^[^.]+.kiya.(cn|us)$

    RewriteRule ^(.+) %{HTTP_HOST}$1 [C]

    RewriteRule ^([^.]+).kiya.(cn|us)(.*)$ /home/www/www.kiya.us/sylvan$3?un=$1&%{QUERY_STRING} [L]

在這段設定中,我把*.kiya.cn和*.kiya.us 的Document Root都設定到了 /home/www/www.kiya.us
繼續看下去,在這裏我就配置了URL Rewrite規則。
RewriteEngine on #打開URL Rewrite功能
RewriteCond %{HTTP_HOST} ^[^.]+.kiya.(cn|us)$ #匹配條件,若是用戶輸入的URL中主機名是相似 xxxx.kiya.us 或者 xxxx.kiya.cn 就執行下面一句
RewriteRule ^(.+) %{HTTP_HOST}$1 [C] #把用戶輸入完整的地址(GET方式的參數除外)做爲參數傳給下一個規則,[C]是Chain串聯下一個規則的意思
RewriteRule ^([^.]+).kiya.(cn|us)(.*)$ /home/www/dev.kiya.us/sylvan$3?un=$1&%{QUERY_STRING} [L]
# 最關鍵的是這一句,使用證則表達式解析用戶輸入的URL地址,把主機名中的用戶名信息做爲名爲un的參數傳給/home/www/dev.kiya.us目錄下的腳本,並在後面跟上用戶輸入的GET方式的傳入參數。並指明這是最後一條規則([L]規則)。注意,在這一句中指明的重寫後的地址用的是服務器上的絕對路徑,這是內部跳轉。若是使用http://xxxx這樣的URL格式,則被稱爲外部跳轉。使用外部跳轉的話,瀏覽着的瀏覽器中的URL地址會改變成新的地址,而使用內部跳轉則瀏覽器中的地址不發生改變,看上去更像實際的二級域名虛擬服務器。
設置後重啓Apache服務器就大功告成了! (從新讓apache從新reload配置便可)

例6. 經過Rewrite防止盜鏈 (常常看到有的網站對圖片盜鏈有限制,其實設置就是這麼簡單)
不容許www.im286.com www.chinaz.com 這兩個網站盜鏈 , 其它的網站均可以盜鏈的規則怎麼寫.

 

1

2

3

4

    RewriteEngine On

    RewriteCond %{HTTP_REFERER} chinaz.com [NC]

    RewriteCond %{HTTP_REFERER} im286.com [NC]

    RewriteRule .*\.(jpg|jpeg|gif|png|rar|zip|txt|ace|torrent|gz|swf)$ http://www.xxx.com/fuck.png [R,NC,L]

 

例7. 關因而否須要使用徹底轉義,好比在 RewriteCond %{HTTP_REFERER} chinaz.com [NC] 中 把 chinaz.com 改爲 chinaz\.com
答案是,二者都是能夠的。

例8. 另外幾個小例子:
1. 屏蔽IE和Opera瀏覽器(User-Agent)

 

1

2

3

4

    RewriteEngine on

    RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR]

    RewriteCond %{HTTP_USER_AGENT} ^Opera [NC]

    RewriteRule ^.* – [F,L]             #這裏"-"表示沒有替換,瀏覽器爲IE和Opera的訪客將被禁止訪問。

2. 自動添加.php擴展名及自動換.html到.php擴展名

 

1

2

3

4

5

6

7

    RewriteEngine On

    RewriteBase /test

    RewriteCond %{REQUEST_FILENAME}.php -f

    RewriteRule ([^/]+)$ /test/$1.php

    #for example: /test/admin => /test/admin.php

    RewriteRule ([^/]+)\.html$ /test/$1.php [L]

    #for example: /test/admin.html => /test/admin.php

3. 限制僅顯示圖片,而不能顯示其餘文件的請求。

 

1

2

3

4

5

6

    #限制目錄只能顯示圖片

    < IfModule mod_rewrite.c>

    RewriteEngine on

    RewriteCond %{REQUEST_FILENAME} !^.*\.(gif|jpg|jpeg|png|swf)$

    RewriteRule .*$ – [F,L]

    < /IfModule>

補充,關於特定文件擴展名的重寫。
重寫有某些擴展名的文件:
RewriteRule (.*.css$|.*.js$) gzip.php?$1 [L]
若是要排除一些擴展名:
RewriteRule !\.(js|ico|gif|jpg|JPG|png|PNG|css|pdf|swf)$ index.php 

參考資料: 摘錄資料的博客1:http://slj.me/2009/04/apache-rewrite-regular/ 摘錄資料的博客2:http://blog.csdn.net/chaiqi/article/details/5620427 apache rewrite官網手冊:http://httpd.apache.org/docs/current/mod/mod_rewrite.html PCRE介紹:http://www.pcre.org/

相關文章
相關標籤/搜索