URL重寫

Apache的URL地址重寫
http://hi.baidu.com/sonan/blog/item/c408963d89468208bba16716.html
第一種方法:Apache環境中如果要將URL地址重寫,正則表達式是最基本的要求,但對於一般的URL地址來說,基本的匹配就能實現我們大部分要求,因此除非 是非常特殊的URL地址,但這不是我要討論的範圍,簡單幾招學會Apache中URL地址重寫,通過實例展示,輕鬆學會URL地址重寫:
URL實例
重寫URL:http://www.baidu.com/?p=152
原始URL:http://www.baidu.com/p152.html
重寫規則:
^p([0-9]+)\.html      /?p=$1     [L]
正則基礎知識:
^ 匹配行的開始,匹配URL地址的開頭部分,對於RewriteRule而言,域名(http://www.biuuu.com)不是URL地址的一部分,如上:?p=152
() 分隔一個被捕獲的表達式,如上:([0-9]+)
[] 定義字符類,如上:[0-9] 表示從0-9的數字
+ 說明前面的字符可以被重複匹配1次或數次,如上:[0-9]+,表示任何數字組合
\ 字符轉義,如上:轉義.
其它:
[L] 表示last,停止匹配其它
方法如下:
1,打開httpd.conf文件,找到
#LoadModule rewrite_module modules/mod_rewrite.so 註釋前面#
2,打開httpd-vhosts.conf文件,在VirtualHost添加重寫規則,
RewriteEngine On
RewriteRule ^p([0-9]+)\.html      /?p=$1     [L]
基本上就上面這兩個步驟,其實總的來說,Apache中URL地址重寫還是比較簡單的,比看文檔學習要快的多,不過要想深入瞭解還是有必要看看相關文檔的,其它規則可以自定義。記住一點:任何匹配其實就是一個正則表達式的替換過程。
創建友好的搜索引擎URL地址對於PHP程序員來說非常重要,因此簡單學會Apache中URL地址重寫將是一項最基本的要求。
第二種方法:
1,首先檢查是否已安裝rewrite模塊:
cat httpd.conf | grep rewrite
LoadModule rewrite_module modules/mod_rewrite.so
2,生成僞靜態html連接:
(1)生成僞靜態html
在<VirtualHost>段最後加入
RewriteEngine on
RewriteRule /goods([0-9]+).html /goods.php?id=$1 [PT] 
更標準的寫法爲:
RewriteRule ^(.*)/goods([0-9]+).html$ $1/goods.php?id=$2 [PT]
更簡潔的寫法:
/goods(\d+)\.html /goods\.php\?id=$1
第一個(0-9]+)對應參數$1,以此類推第二個對應$2
舉例:
RewriteRule /forum-([0-9]+)-([0-9]+)\.html /forumdisplay.php?fid=$1&page=$2 [PT]
測試http://www.xxx.com/goods1.html 是否與/goods.php?id=1的內容相同
最後將所有鏈接換成設置後的僞靜態html地址方式
[PT]:url全局轉換,即轉換過的goods31.html對應goods.php?id=31 (默認就是這個不加參數)
[R]:    url重定向  即使用goods31.html訪問時跳轉到goods.php?id=31
3,防盜鏈:
RewriteCrond %{HTTP_HOST} !upkiller.com [R=301,L]
RewriteRule ^(.*)$ http://www.upkiller.com/warning.html [R=301,L]
把不是來自upkiller.com的請求重定向到http://www.upkiller.com
更好的做法:
RewriteCond %{HTTP_REFERER} !^http://(www\.)?upkiller\.com/.*$ [NC]
RewriteRule \.(mp3|rar|jpe|gif)$ http://www.upkiller.com/warning.jpg [R=301,L]
4,防百度爬蟲:
RewriteCond %{HTTP_USER_AGENT} ^Baiduspider [OR]
RewriteRule ^(.*)$ http://www.google.com [R=301,L]
把來自百度的爬蟲轉到goole
PS:PHP僞靜態方式
方法一: 
比如這個網頁 
http://www.xxxx.com/soft.php/1,100,8630.html 
其實處理的腳本是soft.php 參數爲1,100,8630 
相當於soft.php?a=1&b=1=100&c=8630 只不過這樣的URL太難記。搜索引擎也不喜歡。 
真靜態只是完全生成了HTML。 
客戶端訪問的時候直接輸出。不用腳本解釋。在流量非常大的時候(比如每天有上百萬的訪問量的時候)會起到很好的效果。也就是說服務器端實實在在的存在這個HTML頁面。 
當然在你網站的流量沒有那麼大的時候。URL重寫是最好的方法(個人觀點,大流量的時候可以考慮負載均衡了。同樣沒有關係) 
附URL重寫的方法有很多種,APACHE,IISREWRITE。甚至PHP腳本都可以直接處理。比如上例中就是PHP腳本直接處理(該方法好處是大流量的時候直接減輕WEB伺服器的壓力。PS:同樣也是個人觀點: 
================================================ 
下面以程序爲例講一下PHP僞靜態的程序實現方法,其實這方法我之前已經有在其它論壇社區發過 
程序爲例: 
http://www.xxxx.com/soft.php/1,100,8630.html 
CODE: 
//利用server變量 取得PATH_INFO信息 該例中爲 /1,100,8630.html 也就是執行腳本名後面的部分 
if(@$path_info =$_SERVER["PATH_INFO"]){ 
//正則匹配一下參數 
if(preg_match("/\/(\d+),(\d+),(\d+)\.html/si",$path_info,$arr_path)){ 
$gid =intval($arr_path[1]); //取得值 1 
$sid =intval($arr_path[2]); //取得值100 
$softid =intval($arr_path[3]); //取得值8630 
}else die("Path:Error!"); 
//相當於soft.php?gid=1&sid=100&softid=8630 
//就是這麼簡單了。~) 
方法二: 
一 打開 Apache 的配置文件 httpd.conf 。 
二 將#LoadModule rewrite_module modules/mod_rewrite前面的#去掉 
三 在 httpd.conf中添加: 
<IfModule mod_rewrite.c> 
RewriteEngine On 
#RewriteCond %{ENV:SCRIPT_URL} (?:index|dispbbs)[-0-9]+.html 
RewriteRule ^(.*?(?:index|dispbbs))-([-0-9]+).html 1.php?__is_apache_rewrite=1&__rewrite_arg=2 
</IfModule> 
四 要實現asp帖子URL到php帖子的映射,在 第三步的<IfModule mod_rewrite.c>和</IfModule>之間添加: 
RewriteMap tolowercase int:tolower 
RewriteCond %{QUERY_STRING} (?:boardid|page|id|replyid|star|skin)=d+ [NC] 
RewriteRule ^(.*(?:index|dispbbs)).asp 1.php?{tolowercase:%{QUERY_STRING}}&__is_apache_rewrite=1 
五 保存httpd.conf並重啓Apache 
方法三: 
<?php 
/* 
功能:PHP僞靜態化頁面的實現 
具體用法: 
例如鏈接爲:test.php/year/2006/action/_add.html 
mod_rewrite(); 
$yearn=$_GET["year"];//結果爲'2006' 
$action=$_GET["action"];//結果爲'_add' 
*/ 
function mod_rewrite(){ 
global $_GET; 
$nav=$_SERVER["REQUEST_URI"]; 
$script_name=$_SERVER["SCRIPT_NAME"]; 
$nav=substr(ereg_replace("^$script_name","",urldecode($nav)),1); 
$nav=preg_replace("/^.ht(m){1}(l){0,1}$/","",$nav);//這句是去掉尾部的.html或.htm 
$vars = explode("/",$nav); 
for($i=0;$i<Count($vars);$i+=2){ 
$_GET["$vars[$i]"]=$vars[$i+1]; 

return $_GET; 

mod_rewrite(); 
$yearn=$_GET["year"];//結果爲'2006' 
$action=$_GET["action"];//結果爲'_add' 
echo $yearn; 
echo $action; 
?> 
<?php 
/* 
功能:PHP僞靜態化頁面的實現 
具體用法: 
例如鏈接爲:test.php/year/2006/action/_add.html 
mod_rewrite(); 
$yearn=$_GET["year"];//結果爲'2006' 
$action=$_GET["action"];//結果爲'_add' 
*/ 
function mod_rewrite(){ 
global $_GET; 
$nav=$_SERVER["REQUEST_URI"]; 
$script_name=$_SERVER["SCRIPT_NAME"]; 
$nav=substr(ereg_replace("^$script_name","",urldecode($nav)),1); 
$nav=preg_replace("/^.ht(m){1}(l){0,1}$/","",$nav);//這句是去掉尾部的.html或.htm 
$vars = explode("/",$nav); 
for($i=0;$i<Count($vars);$i+=2){ 
$_GET["$vars[$i]"]=$vars[$i+1]; 

return $_GET; 

mod_rewrite(); 
$yearn=$_GET["year"];//結果爲'2006' 
$action=$_GET["action"];//結果爲'_add' 
echo $yearn; 

echo $action;

=====================================================================================================================

 

Apache的Mod_rewrite學習 (RewriteCond重寫規則的條件)
RewriteCond Syntax: RewriteCond TestString CondPattern [flags]   RewriteCond指令定義一條規則條件。在一條RewriteRule指令前面可能會有一條或多條RewriteCond指令,只有當自身的模 板(pattern)匹配成功且這些條件也滿足時規則才被應用於當前URL處理。   TestString是一個字符串,除了包含普通的字符外,還可以包括下列的可擴展結構:
1.       $N,RewriteRule後向引用,其中(0 <= N <= 9)   $N引用緊跟在RewriteCond後面的RewriteRule中模板中的括號中的模板在當前URL中匹配的數據。
2.       %N,RewriteCond後向引用,其中(0 <= N <= 9)   %N引用最後一個RewriteCond的模板中的括號中的模板在當前URL中匹配的數據。
3.       ${mapname:key|default},RewriteMap擴展. 具體參見RewriteMap 
4.       %{ NAME_OF_VARIABLE } ,服務器變量。 變量的名字如下表(分類顯示) 
   

5.       

6.       特別說明:
o        SCRIPT_FILENAME和REQUEST_FILENAME變量含有相同的值,也就是Apache服務器內部數據結構request_rec的 filename字段的值。第一個變量是一個CGI變量,而第二個則與REQUEST_URI(含有request_rec數據結構中uri字段的值)保 持一致。
o        %{ENV:variable}中的variable可以是任何環境變量的名字。對其值的查找,先通過Apache內部的數據結構,(如找不到)再在Apache服務器進程中通過getenv()查找。
o        %{HTTP:header}中的header可以是任何HTTP MIME-header的名字,其值通過查找HTTP請求信息而得。
o        %{LA-U:variable} 用來引用後續API階段中定義的、當前還不知道的值,具體實現是通過執行一個基於URL的內部的sub-request來決定的variable的最終的 值。例如,假如你想在服務器範圍內利用REMOTE_USER的值來完成重寫,但這個值是在驗證階段設置的,而驗證階段是在URL轉換階段的後面。從另一 方面講,由於mod_rewrite在修補(fixup)API階段進行目錄範圍的重寫,而修補階段在驗證階段的後面,所以此時只要用% {REMOTE_USER}就可以取得該值了。
o        %{LA-F:variable},執行一個基於文件名字(filename)的內部sub-request來決定variable的最終的值。大多數時間內,這和LA-U相同。
  CondPattern是一個條件模板,也就是說,是一個擴展正則式(extended regular expression),用與跟TestString進行匹配。作爲一個標準的擴展正則式,CondPattern有以下補充:
1.       可以在模板串前增加一個!前綴,以用表示不匹配模板。但並不是所有的test都可以加!前綴。
2.       CondPattern中可以使用以下特殊變量:
o        '<CONDPATTERN' (小於,基於字母順序) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 的字符小於CondPattern爲真. 
o        '>CondPattern' (大於) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 的字符大於CondPattern爲真. 
o        '=CondPattern' (等於) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 與CondPattern完全相同時爲真.如果CondPattern只是 "" (兩個引號緊挨在一起) 此時需TestString 爲空字符串方爲真. 
o        '-d' (是否爲目錄) 將testString當作一個目錄名,檢查它是否存在以及是否是一個目錄. 
o        '-f' (是否是regular file) 將testString當作一個文件名,檢查它是否存在以及是否是一個regular文件. 
o        '-s' (是否爲長度不爲0的regular文件) 將testString當作一個文件名,檢查它是否存在以及是否是一個長度大於0的regular文件
o        '-l' (是否爲symbolic link) 將testString當作一個文件名,檢查它是否存在以及是否是一個 symbolic link. 
o        '-F' (通過subrequest來檢查某文件是否可訪問) 檢查TestString是否是一個合法的文件,而且通過服務器範圍內的當前設置的訪問控制進行訪問。這個檢查是通過一個內部subrequest完成 的, 因此需要小心使用這個功能以降低服務器的性能。
o        '-U' (通過subrequest來檢查某個URL是否存在) 檢查TestString是否是一個合法的URL,而且通過服務器範圍內的當前設置的訪問控制進行訪問。這個檢查是通過一個內部subrequest完成 的, 因此需要小心使用這個功能以降低服務器的性能。
  [flags]是第三個參數,多個標誌之間用逗號分隔。
1.       'nocase|NC' (不區分大小寫)   在擴展後的TestString和CondPattern中,比較時不區分文本的大小寫。注意,這個標誌對文件系統和subrequest檢查沒有影響. 
2.       'ornext|OR' (建立與下一個條件的或的關係)   默認的情況下,二個條件之間是AND的關係,用這個標誌將關係改爲OR。例如: RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule ... 如果沒有[OR]標誌,需要寫三個條件/規則.
例子:根據客戶端瀏覽器的不同,返回不同的首頁面。 RewriteCond %{HTTP_USER_AGENT} ^Mozilla.* RewriteRule ^/$ /homepage.max.html [L] RewriteCond %{HTTP_USER_AGENT} ^Lynx.* RewriteRule ^/$ /homepage.min.html [L] RewriteRule ^/$ /homepage.std.html [L] 
當你在地址欄裏輸入 sina.com.cn  google.cn

看看有什麼變化?是不是會自動跳轉到 www.sina.com.cn    www.google.cn

這一技術通過apache的rewrite可以實現,當然你得把 不帶www的域名指向你服務器的IP

 要是虛擬主機的話,得在viralhost段加入 ServerAlias xxx.com

然後打開重寫引擎功能

 RewriteEngine On

能過rewritecond判斷主機名是否帶www

RewriteCond %{HTTP_HOST}  ^xxx\.com$ [NC]

然後來一條

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

OK,重起apache,現在在瀏覽器中輸入 xxx.com 看看是不是自動變成了 www.xxx.com 了呢。

重新整理一下就是:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^xxx\.com$ [NC]

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

 

源地址: http://blog.csdn.net/keyunq/archive/2008/06/11/2536875.aspx

一 .RewriteRule

Syntax: RewriteRule Pattern Substitution [flags]

  一條RewriteRule指令,定義一條重寫規則,規則間的順序 非常重要。對Apache1.2及以後的版本,模板(pattern)是一個POSIX正則式,用以匹配當前的URL。當前的URL不一定是用記最初提交 的URL,因爲可能用一些規則在此規則前已經對URL進行了處理。


  對mod_rewrite來說,!是個合法的模板前綴,表示“非”的意思,這對描述“不滿足某種匹配條件”的情況非常方便,或用作最後一條默認規則。當使用!時,不能在模板中有分組的通配符,也不能做後向引用。

  當匹配成功後,Substitution會被用來替換相應的匹配,它除了可以是普通的字符串以外,還可以包括: 
1. $N,引用RewriteRule模板中匹配的 相關 字串,N表示序號,N=0..9 
2. %N,引用最後一個RewriteCond模板中匹配的數據,N表示序號 
3. %{VARNAME},服務器變量 
4. ${mapname:key|default},映射函數調用


這些特殊內容的擴展,按上述順序進行。
  一個URL的全部相關部分都會被Substitution替換,而且這個替換過程會一直持續到所有的規則都被執行完,除非明確地用L標誌中斷處理過程。
  當susbstitution有”-”前綴時,表示不進行替換,只做匹配檢查。
   利用RewriteRule,可定義含有請求串(Query String)的URL,此時只需在Sustitution中加入一個?,表示此後的內容放入QUERY_STRING變量中。如果要清空一個 QUERY_STRING變量,只需要以?結束Substitution串即可。
  如果給一個Substitution增加一個

1. 'redirect|R [=code]' (強制重定向)
  給當前的URI增加前綴

2. 'forbidden|F' (強制禁止訪問URL所指的資源)
  立即返回狀態值403 (FORBIDDEN)的應答包。將這個標誌與合適的RewriteConds 聯合使用,可以阻斷訪問某些URL。

3. 'gone|G' (強制返回URL所指資源爲不存在(gone))
  立即返回狀態值410 (GONE)的應答包。用這個標誌來標記URL所指的資源永久消失了.

4. # 'proxy|P' (強制將當前URL送往代理模塊(proxy module))
  這個標誌,強制將substitution當作一個發向代理模塊的請求,並立即將共送往代理模塊。因此,必須確保substitution串是一個合法的URI (如, 典型的情況是以

5. 'last|L' (最後一條規則)
  中止重寫流程,不再對當前URL施加更多的重寫規則。這相當於perl的last命令或C的break命令。

6. 'next|N' (下一輪)
  重新從第一條重寫規則開始執行重寫過程,新開的過程中的URL不應當與最初的URL相同。 這相當於Perl的next命令或C的continue命令. 千萬小心不要產生死循環。

7. # 'chain|C' (將當前的規則與其後續規則綑綁(chained))
  當規則匹配時,處理過程與沒有綑綁一樣;如果規則不匹配,則綑綁在一起的後續規則也不在檢查和執行。

8. 'type|T=MIME-type' (強制MIME類型)
  強制將目標文件的MIME-type爲某MIME類型。例如,這可用來模仿mod_alias模塊對某目錄的ScriptAlias指定,通過強制將該目錄下的所有文件的類型改爲 “application/x-httpd-cgi”.

9. 'nosubreq|NS' (used only if no internal sub-request )
   這個標誌強制重寫引擎跳過爲內部sub-request的重寫規則.例如,當mod_include試圖找到某一目錄下的默認文件時 (index.xxx),sub-requests 會在Apache內部發生. Sub-requests並非總是有用的,在某些情況下如果整個規則集施加到它上面,會產生錯誤。利用這個標誌可排除執行一些規則。

10. 'nocase|NC' (模板不區分大小寫)

這個標誌會使得模板匹配當前URL時忽略大小寫的差別。

11. 'qsappend|QSA' (追加請求串(query string))
  這個標誌,強制重寫引擎爲Substitution的請求串追加一部分串,則不是替換掉原來的。藉助這個標誌,可以使用一個重寫規則給請求串增加更多的數據。

12. 'noescape|NE' (不對輸出結果中的特殊字符進行轉義處理)
   通常情況下,mod_write的輸出結果中,特殊字符(如'%', '$', ';', 等)會轉義爲它們的16進制形式(如分別爲'%25', '%24', and '%3B')。這個標誌會禁止mod_rewrite對輸出結果進行此類操作。 這個標誌只能在 Apache 1.3.20及以後的版本中使用。

13. 'passthrough|PT' (通過下一個處理器)
   這個標誌強制重寫引擎用filename字段的值來替換內部request_rec數據結構中uri字段的值。. 使用這個標誌,可以使後續的其它URI-to-filename轉換器的Alias、ScriptAlias、Redirect等指令,也能正常處理 RewriteRule指令的輸出結果。用一個小例子來說明它的語義:如果要用mod_rewrite的重寫引擎將/abc轉換爲/def,然後用 mod_alas將/def重寫爲ghi,則要:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi
如 果PT標誌被忽略,則mod_rewrite也能很好完成工作,如果., 將 uri=/abc/... 轉換爲filename=/def/... ,完全符合一個URI-to-filename轉換器的動作。接下來 mod_alias 試圖做 URI-to-filename 轉換時就會出問題。
注意:如果要混合都含有URL-to-filename轉換器的不同的模塊的指令,必須用這個標誌。最典型的例子是mod_alias和mod_rewrite的使用。

14. 'skip|S=num' (跳過後面的num個規則)
  當前規則匹配時,強制重寫引擎跳過後續的num個規則。用這個可以來模仿if-then-else結構:then子句的最後一條rule的標誌是skip=N,而N是else子句的規則條數。

15. 'env|E=VAR:VAL' (設置環境變量)
   設置名爲VAR的環境變量的值爲VAL,其中VAL中可以含有正則式的後向引用($N或%N)。這個標誌可以使用多次,以設置多個環境變量。這兒設置的 變量,可以在多種情況下被引用,如在XSSI或CGI中。另外,也可以在RewriteCond模板中以%{ENV:VAR}的形式被引用。

16. 

   注意:一定不要忘記,在服務器範圍內的配置文件中,模板(pattern)用以匹配整個URL;而在目錄範圍內的配置文件中,目錄前綴總是被自動去掉後再 進行模板匹配的,且在替換完成後自動再加上這個前綴。這個功能對很多種類的重寫是非常重要的,因爲如果沒有去前綴,則要進行父目錄的匹配,而父目錄的信息 並不是總能得到的。一個例外是,當substitution中有http://打頭時,則不再自動增加前綴了,如果P標誌出現,則會強制轉向代理。

注 意:如果要在某個目錄範圍內啓動重寫引擎,則需要在相應的目錄配置文件中設置“RewriteEngine on”,且目錄的“Options FollowSymLinks”必須設置。如果管理員由於安全原因沒有打開FollowSymLinks,則不能使用重寫引擎。

http://hostname 開頭),否則會從代理模塊得到一個錯誤. 這個標誌,是ProxyPass指令的一個更強勁的實現,將遠程請求(remote stuff)映射到本地服務器的名字空間(namespace)中來。
   注意,使用這個功能必須確保代理模塊已經編譯到Apache 服務器程序中了. 可以用“httpd -l ”命令,來檢查輸出中是否含有mod_proxy.c來確認一下。如果沒有,而又需要使用這個功能,則需要重新編譯``httpd''程序並使用 mod_proxy有效。 http://thishost[:thisport]/ , 從而生成一個新的URL,強制生成一個外部重定向(external redirection,指生的URL發送到客戶端,由客戶端再次以新的URL發出請求,雖然新URL仍指向當前的服務器). 如果沒有指定的code值,則HTTP應答以狀態值302 (MOVED TEMPORARILY),如果想使用300-400(不含400)間的其它值可以通過在code的位置以相應的數字指定,也可以用標誌名指定: temp (默認值), permanent, seeother.

注意,當使用這個標誌時,要確實substitution是個合法的URL,這個標誌只是在URL前增加http://thishost[:thisport]/ 前綴而已,重寫操作會繼續進行。如果要立即將新URL重定向,用L標誌來中重寫流程。http://thishost[:port ]的前綴,則mod_rewrite會自動將此前綴去掉。因此,利用 http://thisthost 做一個無條件的重定向到自己,將難以奏效。要實現這種效果,必須使用R標誌。
  Flags是可選參數,當有多個標誌同時出現時,彼此間以逗號分隔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章