Apache Rewrite實現URL的跳轉和域名跳轉

RewriteCond 和RewriteRule
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]
 
 
一 .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是可選參數,當有多個標誌同時出現時,彼此間以逗號分隔。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章