標籤:
Rewirte主要的功能就是實現URL的跳轉,它的Regex是基於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.domain.cn和202.91.246.20都跳 轉到主機首碼為http://www.domain.cn, 避免相同內容的網頁有多個指向的網域名稱,如http://domain.cn。
NameVirtualHost 202.91.246.20:80
ServerAdmin [email protected]
DocumentRoot “/web”
ServerName domain.cn
RewriteEngine on #開啟rewirte功能
RewriteCond %{HTTP_HOST} !^www.domain.cn [NC] #聲明Client請求的主機中首碼不是www.domain.cn, 其中 [NC] 的意思是忽略大小寫
RewriteCond %{HTTP_HOST} !^202.91.246.20 [NC] #聲明Client請求的主機中首碼不是202.91.246.20,其中 [NC] 的意思是忽略大小寫
RewriteCond %{HTTP_HOST} !^$ #聲明Client請求的主機中首碼不為空白
RewriteRule ^(.*) http://www.kiya.cn/ [L] #含義是如果Client請求的主機中的首碼符合上述條件,則直接進行跳轉到http://www.kiya.cn/,[L]意味著立即停止重寫操作,並 不再應用其他重寫規則。這裡的.*是指匹配所有URL中不包含換行字元,()括弧的功能是把所有的字元做一個標記,以便於後面的應用.就是引用前面裡的 (.*)字元。
例二.將輸入 example.com 的網域名稱時跳轉到http:www.domain.cn
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*) http://www.domain.cn/ [L]
例三.賽卡軟體近期更換了網域名稱,新網域名稱為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
按照這樣的要求重新導向規則應該這樣寫:
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]
3.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) 設定環境變數
4.Apache rewrite例子集合
URL重新導向
例子一:
同時達到下面兩個要求:
1.用http://www.domain.cn/xxx.php 來訪問http://www.domain.cn/xxx/
2.用http://xiaoye.domain.cn 來訪問 http://www.domain.cn/user.php?username=xiaoye的功能
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.domain.cn
RewriteCond %{REQUEST_URI} !^user.php$
RewriteCond %{REQUEST_URI} .php$
RewriteRule (.*).php$ http://www.domain.cn/$1/ [R]
RewriteCond %{HTTP_HOST} !^www.domain.cn
RewriteRule ^(.+) %{HTTP_HOST} [C]
RewriteRule ^([^.]+).domain.cn http://www.domain.cn/user.php?username=$1
例子二:
/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]
5.使用Apache的URL Rewrite配置多使用者虛擬伺服器
要實現這個功能,首先要在DNS伺服器上開啟網域名稱的泛網域名稱解析(自己做或者找網域名稱服務 (DNS)商做)。比如,我就把 *.kiya.us和 *.kiya.cn全部解析到了我的IP地址70.40.213.183上。
然後,看一下我的Apache中關於*.kiya.us的虛擬機器主機的設定。
ServerAdmin [email protected]
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
#AddDefaultCharset GB2312
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伺服器就大功告成了!
Update May 1, 2009
今天上網看到了有人提一個問題:
求Rewrite 防盜鏈正則
不允許www.im286.com www.chinaz.com 這兩個網站盜鏈 , 其它的網站都可以盜鏈的規則怎麼寫.
論壇中的答案是:
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]
Update May 7, 2009
介紹一篇文章:http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/mod_rewrite.html
Update May 24, 2009
一、關於是否需要使用完全轉義,比如在 RewriteCond %{HTTP_REFERER} chinaz.com [NC] 中 把 chinaz.com 改成 chinaz\.com
答案是,兩者都是可以的。
二、今天在做 YOURcaddy.com (就是我去年做的PlanetCoachella的變形)的時候,在 GoDaddy 主機上無法正常轉向,後來找到了問題:
在HostMonster以及我自己的機器上,是用
RewriteRule ^business/([^\.]+)$ biz/detail.php?name=$1 [L]
達到改寫的。而在Godaddy主機上,是這樣:
RewriteRule ^business/([^\.]+)$ /biz/detail.php?name=$1 [L]
目標檔案前多了一個/
現在想想,可能是因為沒有指定RewriteBase,至於到底是不是我改日再驗證一下。
三、添加兩個關於判斷 USER AGENT 例子和自動添加.php副檔名及自動換.html到.php副檔名的例子:
1
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ^MSIE [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Opera [NC]
RewriteRule ^.* – [F,L] 這裡”-”表示沒有替換,瀏覽器為IE和Opera的訪客將被禁止訪問。
2
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
限制目錄只能顯示圖片
< IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !^.*\.(gif|jpg|jpeg|png|swf)$
RewriteRule .*$ – [F,L]
< /IfModule>
Update Jun 10, 2009
補充,關於特定副檔名的重寫。
重寫有某些副檔名的檔案:
RewriteRule (.*.css$|.*.js$) gzip.php?$1 [L]
如果要排除一些副檔名:
RewriteRule !\.(js|ico|gif|jpg|JPG|png|PNG|css|pdf|swf)$ index.php
來源:http://www.cnblogs.com/yeer/archive/2010/08/17/1801679.html
Apache Rewrite實現URL的跳轉和網域名稱跳轉