一:目的 

      本文旨在提供如何用Apache重寫規則來解決一些常見的URL重寫方法的問題,通過常見的
      實例給用戶一些使用重寫規則的基本方法和線索。 

      二:為什需要用重寫規則? 
      一個網站,如果是長期需要放在internet上提供服務,必定會有不斷地更新和維護,如臨
      時轉移到其它服務器進行維護,重新組織目錄結構,變換URL甚至改變到新的域名等等,
      而為了讓客戶不會因此受到任何影響,最好的方法就是使用Apache Rewrite Rule(重寫
      規則)。 

      三: 重寫規則的作用范圍 
      1) 可以使用在Apache主配置文件httpd.conf中 
      2) 可以使用在httpd.conf裡定義的虛擬主機配置中 
      3) 可以使用在基本目錄的跨越配置文件.htaccess中 

      四:重寫規則的應用條件 
      只有當用戶的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服務
      器的請求。 

      五:重寫規則怎樣工作? 
      我們假定在編譯Apache時已經把mod_rewrite編譯成模塊,確信你的httpd.conf中有 
      LoadModule rewrite_module libexec/mod_rewrite.so 
      並且在Addmodule中有 
      Addmodule mod_rewrite.c 
      則可以使用重寫規則。 
      當外部請求來到Apache,Apache調用重寫規則中的定義來重寫由用戶瀏覽器指定請求的
      URI,最被重寫的URI如果是重定向,則送由瀏覽器作再一次請求;如果是代理則把重寫
      的URI交給代理模塊請求最終的內容(Content),最把內容送回給瀏覽器。 

      六: 何時使用.htaccess中的重寫規則定義? 
      假如你對你的的網站內容所在的服務器沒有管理員權限,或者你的網站放在ISP的服務器
      上托管等等條件下,你無法改寫主配置文件,然而你可以對你的WEB站點內容所在的目錄
      有寫權限,則你可以設置自己的.htaccess 
      文件達到同樣的目的。但你需要確定主配置文件中對你的網站所在的目錄定義了下面的內
      容: 

      Options Indexes FollowSymLinks 
      AllowOverride all 

      否則你的.htaccess不會工作。 

      七: 應用舉例 
      假定Apache被編譯安裝在主機192.168.1.56的/usr/local/apache/ 目錄下面,我們編
      譯進了重寫和代理模塊。 

      1) 隱藏Apache下的某個目錄,使得對該目錄的任何請求都重定向到另一個文件。 

      a> httpd.conf的實現方法 

      我們放下面的部分到/usr/local/apache/conf/httpd.conf 


      options Indexes followsymlinks 
      allowoverride all 
      rewriteengine on 
      rewritebase / 
      rewriterule ^(.*)$ index.html.en [R=301] 


      注:rewriteengine on 為重寫引擎開關,如果設為off,則任何重寫規則定義將不被應
      用,該開關的另一好處就是如果為了臨時拿掉重寫規則,則改為off再重啟動Apache即
      可,不必將下面一條條的重寫規則注釋掉。 
      rewritebase / 的作用是如果在下面的rewriterule定義中被重寫的部分(此處為文件
      名index.html.en)前面沒有/,則是相對目錄,相對這個rewritebase面的定義也就
      是/usr/local/apache/htdocs/index.html.en,否則,如果此處沒有rewritebase /這
      一項,則被重寫成 
      http://192.168.1.56/usr/local/apache/htdocs/manual/index.html.en ,顯然是
      不正確的。 

      不過這裡我們也可以不用rewritebase / , 而改為 
      rewriteengine on 
      rewriterule ^(.*)$ /index.html.en [R=301] 
      或者 
      rewriteengine on 
      rewriterule ^(.*)$ http://192.168.1.56/index.html.en [R=301] 

      b> .htaccess的實現方法 

      我們先放下面的部分到httpd.conf 


      options Indexes followsymlinks 
      allowoverride all 


      然放下面的部分到/usr/local/apache/htdocs/manual/.htaccess中 
      rewriteengine on 
      rewritebase / 
      rewriterule ^(.*)$ index.html.en [R=301] 

      注:對文件.htaccess所作的任何改動不需要重啟動Apache. 

      問:要是把這個manual目錄重定向到用戶jephe的自己的主目錄呢? 
      用下面的.htaccess方案。 
      rewriteengine on 
      rewritebase /~jephe/ 
      rewriterule ^(.*)$ $1 [R=301] 

      則對manual目錄下任何文件的請求被重定向到~jephe目錄下相同文件的請求。 

      2) 轉換www.username.domain.com的對username的主頁請求為
      www.domain.com/username 

      對HTTP/1.1的請求包括一個Host: HTTP頭,我們能用下面的規則集重寫 
      http://www.username.domain.com/anypath 到 /home/username/anypath 

      Rewriteengine on 
      rewritecond %{HTTP_HOST} ^www\.[^.]+\.host\.com$ 
      rewriterule ^(.+) %{HTTP_HOST}$1 [C] 
      rewriterule ^www\.([^.]+)\.host\.com(.*) /home/$1$2 

      注: 
      rewritecond 條件重寫規則,當滿足面定義的條件才會應用下面的重寫規則,
      rewritecond有各種變量 
      ,請查閱相關文檔。 

      3) 防火牆上的重寫規則代理內部網段上服務器的請求。 

      NameVirtualhost 1.2.3.4 


      servername www.domain.com 
      rewriteengine on 
      proxyrequest on 
      rewriterule ^/(.*)$ http://192.168.1.3/$1 [P,L] 


      注:當外部瀏覽器請求www.domain.com時被解析到IP地址1.2.3.4 ,Apache 交出
      mod_rewrite處理轉換成 
      http://192.168.1.3/$1再交由代理模塊mod_proxy得到內容傳送回用戶的瀏覽器。


      4) 基本預先設定的轉換MAP表進行重寫 rewritemap 

      轉換www.domain.com/{countrycode}/anypath 到Map表中規定的URI,上面是虛擬主機
      中的定義 

      rewritelog /usr/local/apache/logs/rewrite.log 
      rewriteloglevel 9 

      rewriteengine on 
      proxyrequest on 
      rewritemap sitemap txt:/usr/local/apache/conf/rewrite.map 
      rewriterule ^/([^/]+)+/(.*)$ http://%{REMOTE_HOST}::$1 [C] 
      rewriterule (.*)::([a-z]+)$ ${sitemap:$2|http://h.i.j.k/} [R=301,L] 

      文件/usr/local/apache/conf/rewrite.map的內容如下: 

      sg http://a.b.c.d/ 
      sh http://e.f.g.h/ 

      注: 當用戶請求http://www.domain.com/sg/anypath時被重寫為
      http://a.b.c.d/anypath . 
      當需要調試時請用rewritelog and rewriteloglevel 9聯合,9為最大即得到最多的調試
      信息 
      最小為1,最小的調試信息,默認為0,沒有調試信息。 
      sitemap的語法是${sitemap: LookupKey | Defaultvalue} ,有些書上把$寫成了%是錯
      誤的。 

    全站熱搜

    jianmin2 發表在 痞客邦 留言(0) 人氣()