天天看點

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 } ,伺服器變量。 變量的名字如下表(分類顯示)

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

5.       

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

6.       特别說明:

o       

SCRIPT_FILENAME和REQUEST_FILENAME變量含有相同的值,也就是Apache伺服器内部資料結構request_rec的

filename字段的值。第一個變量是一個CGI變量,而第二個則與REQUEST_URI(含有request_rec資料結構中uri字段的值)保持一緻。

%{ENV:variable}中的variable可以是任何環境變量的名字。對其值的查找,先通過Apache内部的資料結構,(如找不到)再在Apache伺服器程序中通過getenv()查找。

%{HTTP:header}中的header可以是任何HTTP MIME-header的名字,其值通過查找HTTP請求資訊而得。

%{LA-U:variable}

用來引用後續API階段中定義的、目前還不知道的值,具體實作是通過執行一個基于URL的内部的sub-request來決定的variable的最終的值。例如,假如你想在伺服器範圍内利用REMOTE_USER的值來完成重寫,但這個值是在驗證階段設定的,而驗證階段是在URL轉換階段的後面。從另一方面講,由于mod_rewrite在修補(fixup)API階段進行目錄範圍的重寫,而修補階段在驗證階段的後面,是以此時隻要用%

{REMOTE_USER}就可以取得該值了。

%{LA-F:variable},執行一個基于檔案名字(filename)的内部sub-request來決定variable的最終的值。大多數時間内,這和LA-U相同。

  CondPattern是一個條件模闆,也就是說,是一個擴充正則式(extended

regular expression),用與跟TestString進行比對。作為一個标準的擴充正則式,CondPattern有以下補充:

可以在模闆串前增加一個!字首,以用表示不比對模闆。但并不是所有的test都可以加!字首。

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]

源位址: 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是可選參數,當有多個标志同時出現時,彼此間以逗号分隔。