mod_rewrite使用總結
前提需求:
modrewite 將URL定向到另一個目錄或檔案,而地址欄URL不變,網頁內容為新地址內容。
http://www.test.com/a/b 顯示 http://www.test.com/test/的內容,URL地址還保持為
www.test.com/a/b
根據下面操作自己可以更加靈活變動
參考串連
http://fanqiang.chinaunix.net/a6/b1/20010905/0800001238.html
一、實現原理:
(主要看第2點)
只有當使用者的WEB請求最終被導向到某台WEB伺服器的Apache後台,則這台WEB伺服器接受
進來的請求,根據設定檔該請求是主配置還是虛擬機器主機,再根據使用者在瀏覽器中請求的
URI來配對重寫規則並且根據實際的請求路徑配對.htaccess中的重寫規則。最後把請求
的內容傳回給使用者,該響應可能有兩種:
1) 對瀏覽器請求內容的外部重新導向(Redirect)到另一個URL。
讓瀏覽器再次以新的URI發出請求(R=301或者R=302,臨時的或是永久的重新導向)
如:一個網站有正規的URL和別名URL,對別名URL進行重新導向到正規URL,或者網站改換
成了新的網域名稱
則把舊的網域名稱重新導向到新的網域名稱(Redirect)
2) 也可能是由Apache內部子請求代理產生新的內容送回給客戶[P,L]
這是Apache內部根據重寫後的URI內部通過代理模組請求內容並送回內容給客戶,而客戶
端瀏覽器並
不知道,瀏覽器中的URI不會被重寫。但實際內容被Apache根據重寫規則後的URI得到。
如:在公司防火牆上啟動並執行Apache啟動這種代理重寫規則,代理對內部網段上的WEB服務
器的請求。
說明:為了不讓地址URL被重寫,而內容重新導向,使用apache mod_proxy代理模組的反向 Proxy功能
實現。
二、簡單說一下mod_proxy
Apache可以被配置為正向(forward)和反向(reverse)代理。
正向 Proxy是一個位於用戶端和原始伺服器(origin server)之間的伺服器,為了從原始伺服器取得
內容,用戶端向代理髮送一個請求並指定目標(原始伺服器),然後代理向原始伺服器轉交請求並
將獲得的內容返回給用戶端。用戶端必須要進行一些特別的設定才能使用正向 Proxy。
正向 Proxy的典型用途是為在防火牆內的區域網路用戶端提供訪問Internet的途徑。正向 Proxy還可以
使用緩衝特性(由mod_cache提供)減少網路使用率。
使用ProxyRequests指令即可啟用正向 Proxy。因為正向 Proxy允許用戶端通過它訪問任意網站並且隱
藏用戶端自身,因此你必須採取安全措施以確保僅為經過授權的用戶端提供服務。
反向 Proxy正好相反,對於用戶端而言它就像是原始伺服器,並且用戶端不需要進行任何特別的設
置。用戶端向反向 Proxy的名字空間(name-space)中的內容發送普通請求,接著反向 Proxy將判斷向
何處(原始伺服器)轉交請求,並將獲得的內容返回給用戶端,就像這些內容原本就是它自己的一
樣。
反向 Proxy的典型用途是將防火牆後面的伺服器提供給Internet使用者訪問。反向 Proxy還可以為後端
的多台伺服器提供Server Load Balancer,或為後端較慢的伺服器提供緩衝服務。另外,還可以啟用進階URL策
略和管理技術,從而使處於不同web伺服器系統的web頁面同時存在於同一個URL空間下。
可以使用ProxyPass指令啟用反向 Proxy(在RewriteRule指令中使用[P]標記也可以)。配置反向 Proxy
並不需要開啟ProxyRequests指令。
簡單樣本:
正向 Proxy
ProxyRequests On
ProxyVia On
<Proxy *>
Order deny,allow
Deny from all
Allow from internal.example.com
</Proxy>
反向 Proxy
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar
三、mod_rewrite的具體使用方法,我在這裡就不多說了,請看這個連結:
http://bbs.chinaunix.net/viewthread.php?tid=66521&extra=page%3D2
四、開始安裝!!!!!!
仔細看上面理論說明,具體操作沒有幾步的,越來越覺得理論基礎非常重要!!!
1、安裝apache2.0
cd apache2.0
./configure --enable-MODULE=shared --enable-so --with-mpm=worker --enable-
rewrite=shared --enable-proxy=shared
說明:
--enable-proxy=shared 加入mod_proxy模組
--enable-rewrite=shared 加入mod_rewrite模組
對於編譯mod_rewrite模組,我多說幾句:
按照上面的方法,rewrite模組已經正常編譯進了./apache2/module/目錄裡了,而且設定檔
LoadModule也添加相關路徑了,可是我使用時rewrite卻不能重寫,所以我又手動添加了一次,這
個方法同樣也適合不想重新安裝apache,採用手動添加的方法。
cd 原始碼目錄
find ./ -name mod_rewrite.c
cd PATH/to/mod_rewrite.c
/usr/local/apache2/bin/apxs -c mod_rewrite.c
/usr/local/apache2/bin/apxs -i -a -n mod_rewrite mod_rewrite.la
如果出現這個錯誤
Syntax error on line 329 of /usr/local/apache2/conf/httpd.conf:
Can`t loacte API module staructure `mod_rewrite_module` in file
/usr/local/apache2/modules/mod_rewrite.so:/usr/local/apache2/lib/libapr-
0.so.0:undefined symbol:mod_rewrite_module
修改http.conf
原來:httpd.conf裡面寫的mod_rewrite_module
改成 rewrite_module
如果重啟apache出現這個錯誤module rewrite_module is built-in and can`t be loaded
表示模組是內建的,不用再調入
結束。
2、修改設定檔
vi conf/httpd.conf
添加下面內容:
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
啟用mod_proxy反向 Proxy
NameVirtualHost 192.168.0.203:80
<VirtualHost 192.168.0.203:80>
ServerAdmin test@test.com
DocumentRoot /test
ServerName www.test.com
ErrorLog logs/ip-error_log
RewriteEngine on
RewriteCond %{REQUEST_URI} /[^&]+/b/
RewriteCond %{REQUEST_URI} !/test/
RewriteCond %{HTTP_HOST} ^www/.test/.com [NC]
RewriteRule ^/(.*) http://www.test.com/test/ [P,L]
</VirtualHost>
這幾個條件和規則的意思是:如果輸入www.test.com ([^&]+表示任一字元)並且後面的URI為
a/b/形式,則跳到www.test.com/test/ 如果輸入的是www.test.com/test/則不跳轉。[P]這個參
數很重要,使用反向 Proxy方式應該使用者請求。
經過上面這幾步,就是可以實現前面的需求。
下面為使用執行個體:
1、
RewriteCond %{THE_REQUEST} ^[^/]+/[^&^/]+/blog[^/?]*/ HTTP/
RewriteCond %{HTTP_HOST} ^www/.test/.com [NC] (這個條件不加也可以,如果不限制主機名稱
)
RewriteRule ^(.*)/(.*)/blog([^/?]*) $1/space/blog$3?username=$2 [L,R]
2、
RewriteCond %{REQUEST_URI} ^/[^&^/]+/blog
RewriteCond %{REQUEST_URI} !/space/blog/
RewriteCond %{HTTP_HOST} ^www/.203wdxc/.cn [NC]
RewriteRule ^(.*)/([a-z]+)/blog(.*) $1/space/blog$3?username=$2 [P,L]
3、
RewriteCond %{REQUEST_URI} /[^&]+/blog/
RewriteCond %{REQUEST_URI} !/space/blog/
RewriteCond %{HTTP_HOST} ^www/.test/.cn [NC]
RewriteRule ^/(.*) http://www.test.cn/space/ [P,L]
http://www.test.cn/name/blog 跳到http://www.test.cn/space/ 如果是/space/blog/不跳轉
5、
http://www.example.com/swf/test.swf?member_name=finalbsd&album_id=24
重寫成:
http://www.example.com/swf/finalbsd/24/test.swf
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}/ /swf/([^&]+)/.swf/?member_name=([^&]+)
&album_id=([^&]+)/ HTTP/
RewriteRule ^/swf/([^&]+)/.swf$ http://www.example.com/swf/%2/%3/%1.swf? [R]
6、
RewriteCond %{THE_REQUEST} ^[^/]+/[^/]+/blog/ HTTP
RewriteRule ^(.*)/(.*)/blog $1/space/blog?username=$2 [L,R]
RewriteCond %{THE_REQUEST} ^[^/]+/[^/]+/blog// HTTP
RewriteRule ^(.*)/(.*)/blog/ $1/space/blog/?username=$2 [L,R]
RewriteCond %{THE_REQUEST} ^[^/]+/[^/]+/blog/[^/?]*/ HTTP
RewriteRule ^(.*)/(.*)/blog/([^/?]*) $1/space/blog/$3?username=$2 [L,R]
7、
#三種情況,所以寫了三個條件三個規則
RewriteCond %{REQUEST_URI} !/space/blog
RewriteCond %{THE_REQUEST} ^GET/ /[^/]+/blog/ HTTP
RewriteRule ^(.*)/(.*)/blog $1/space/blog?username=$2 [L,R]
RewriteCond %{REQUEST_URI} !/space/blog/
RewriteCond %{THE_REQUEST} ^GET/ /[^/]+/blog// HTTP
RewriteRule ^(.*)/(.*)/blog/ $1/space/blog/?username=$2 [L,R]
RewriteCond %{REQUEST_URI} !/space/blog/[^/?]*
RewriteCond %{THE_REQUEST} ^GET/ /[^/]+/blog/[^/?]*/ HTTP
RewriteRule ^(.*)/(.*)/blog/([^/?]*) $1/space/blog/$3?username=$2 [L,R]
8、
9.
RewriteCond %{REQUEST_URI} !/[a-z]+/.*
RewriteCond %{HTTP_HOST} ^[^&]+/.blog/.test/.com [NC]
RewriteRule ^/(.*)$ $2/a/b/$1 [L,R]
解釋一下:前兩句就是定義條件,如果任意一個這樣的地址http://user1.blog.test.com 後面沒
有子路徑時,才執行第三句的重寫規則,重寫為http://user1.test.com/a/b 而對於
http://user1.blog.test.com/photo 不進行重寫.
10、
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
NameVirtualHost 192.168.0.191:80
<VirtualHost 192.168.0.191:80>
DocumentRoot /test
ServerName www.test.cn
RewriteEngine on
RewriteCond %{REQUEST_URI} !/space/blog
RewriteCond %{THE_REQUEST} ^[^/]+/[^/]+/blog/ HTTP
RewriteRule ^(.*)/(.*)/blog $1/space/blog/?username=$2 [P,L]
RewriteCond %{REQUEST_URI} !/space/blog/
RewriteCond %{THE_REQUEST} ^[^/]+/[^/]+/blog// HTTP
RewriteRule ^(.*)/(.*)/blog/ $1/space/blog/?username=$2 [P,L]
RewriteCond %{REQUEST_URI} !/space/blog/[^/?]*
RewriteCond %{THE_REQUEST} ^[^/]+/[^/]+/blog/[^/?]*/ HTTP
RewriteRule ^(.*)/(.*)/blog/([^/?]*) $1/space/blog/$3?username=$2 [P,L]
</VirtualHost>
http://www.test.com/name/blog 跳到 http://www.test.com/space/blog?username=name 但是
地址不發生變化,因為使用了[P]代理請求。
11、
RewriteCond %{HTTP_HOST} ^(.*).aaaa/.cn [NC]
RewriteRule ^(.*)$ http://%1.vvvv.cn/$1 [R=permanent,L]
RewriteCond %{REQUEST_URI} !^/space/blog/.*
RewriteCond %{HTTP_HOST} ^[^&]+/.blog/.aaa/.cn [NC]
RewriteCond %{THE_REQUEST} !^[^&]/.*/ HTTP/ [NC]
RewriteRule ^/(.*)$ $2/space/blog/$1 [L,R]
RewriteCond %{REQUEST_URI} !/[a-z]+/.*
#{REQUEST_URI}的意思是這是在HTTP請求行中所請求的資源(比
如"/index.html"或/test/test.html), [^&]表示裡面是任一字元,^表示行首第一個字元,&表示
行尾字元, !表示否的意思或不包括的意思,+ 表示它前面的那個字元出現大於零的個數,.表示
單個任一字元,*表示前面字元出現任意個,也可以一次也不出現,RewriteCond 表示條件。整句
的意思就是:設定一個條件為,不包括一個請求資源的子路徑(/test/test.html)為任何資源,而
不是URL,再說的直白一點,就是輸入了一個地址http://www.test.com後面沒有輸
入/test/test.html等形式的地址情況下。再看下面就這句就會更加明白。
RewriteCond %{HTTP_HOST} ^[^&]+/.blog/.191wdxc/.cn [NC]
{HTTP_HOST}意思是請求的是一個完整FQDN形式的地址,就是www.test.com, [NC]表示忽略大小字
母。
第一句和第二句合起來理解就是,設定了條件,一個請求地址是[^&].blog.aaa.cn並且後沒
有輸入子路徑時才可以執行下面的規則。如果不滿足這個條件的,就不進行rewrite.
RewriteRule ^/(.*)$ $2/space/blog/$1 [L,R]
這句就是重寫規則了。$2表示使用了反向引用,(.*)這部分內容,就是用$2引用,$就是用$1引用
,這樣重寫之後就是這樣http://[^&].blog.aaa.cn/space/blog
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/paulluo0739/archive/2009/04/21/4097974.aspx