RewriteCond指令格式
語法: RewriteCond TestString CondPattern [flags]
RewriteCond指令定義一條規則條件。在一條RewriteRule指令前麵可能會有一條或多條RewriteCond指令,隻有當自身的模板(pattern)匹配成功且這些條件也滿足時規則才被應用於當前URL處理。
1、 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擴展。
2、CondPattern是條件pattern, 即一個應用於當前實例TestString的正則表達式, 即TestString將會被計算然後與CondPattern匹配。作為一個標準的擴展正則式,CondPattern有以下補充:
1)可以在模板串前增加一個!前綴,以用表示不匹配模板。但並不是所有的test都可以加!前綴。
2)CondPattern中可以使用以下特殊變量:
'<CONDPATTERN' (小於,基於字母順序) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 的字符小於CondPattern為真。
'>CondPattern' (大於) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 的字符大於CondPattern為真。
'=CondPattern' (等於) 將condPattern當作一個普通字符串,將它和TestString進行比較,當TestString 與CondPattern完全相同時為真.如果CondPattern隻是 "" (兩個引號緊挨在一起) 此時需TestString 為空字符串方為真。
'-d' (是否為目錄) 將testString當作一個目錄名,檢查它是否存在以及是否是一個目錄。
'-f' (是否是regular file) 將testString當作一個文件名,檢查它是否存在以及是否是一個regular文件。
'-s' (是否為長度不為0的regular文件) 將testString當作一個文件名,檢查它是否存在以及是否是一個長度大於0的regular文件。
'-l' (是否為symbolic link) 將testString當作一個文件名,檢查它是否存在以及是否是一個 symbolic link。
'-F' (通過subrequest來檢查某文件是否可訪問) 檢查TestString是否是一個合法的文件,而且通過服務器範圍內的當前設置的訪問控製進行訪問。這個檢查是通過一個內部subrequest完成的, 因此需要小心使用這個功能以降低服務器的性能。
'-U' (通過subrequest來檢查某個URL是否存在) 檢查TestString是否是一個合法的URL,而且通過服務器範圍內的當前設置的訪問控製進行訪問。這個檢查是通過一個內部subrequest完成的, 因此需要小心使用這個功能以降低服務器的性能。
3、[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]標誌,需要寫三個條件/規則.
RewriteRule 指令
語法: RewriteRule Pattern Substitution [flags]
1) Pattern是一個作用於當前URL的兼容perl的正則表達式. 這裏的“當前''是指該規則生效時的URL的值。
2) Substitution是,當原始URL與Pattern相匹配時,用以替代(或替換)的字符串。
3) 此外,Substitution還可以追加特殊標記[flags] 作為RewriteRule指令的第三個參數。 Flags是一個包含以逗號分隔的下列標記的列表:
redirect|R [=code] (強製重定向 redirect)
以 http://thishost[:thisport]/(使新的URL成為一個URI) 為前綴的Substitution可以強製性執行一個外部重定向。 如果code沒有指定,則產生一個HTTP響應代碼302(臨時性移動)。 如果需要使用在300-400範圍內的其他響應代碼,隻需在此指定這個數值即可, 另外,還可以使用下列符號名稱之一: temp (默認的), permanent, seeother. 用它可以把規範化的URL反饋給客戶端,如, 重寫“/~''為 “/u/'',或對/u/user加上斜杠,等等。
注意: 在使用這個標記時,必須確保該替換字段是一個有效的URL! 否則,它會指向一個無效的位置! 並且要記住,此標記本身隻是對URL加上 http://thishost[:thisport]/的前綴,重寫操作仍然會繼續。 通常,你會希望停止重寫操作而立即重定向,則還需要使用'L'標記.
forbidden|F (強製URL為被禁止的 forbidden)
強製當前URL為被禁止的,即,立即反饋一個HTTP響應代碼403(被禁止的)。 使用這個標記,可以鏈接若幹RewriteConds以有條件地阻塞某些URL。
gone|G'(強製URL為已廢棄的 gone)
強製當前URL為已廢棄的,即,立即反饋一個HTTP響應代碼410(已廢棄的)。 使用這個標記,可以標明頁麵已經被廢棄而不存在了.
proxy|P (強製為代理 proxy)
此標記使替換成分被內部地強製為代理請求,並立即(即, 重寫規則處理立即中斷)把處理移交給代理模塊。 你必須確保此替換串是一個有效的(比如常見的以 http://hostname開頭的)能夠為Apache代理模塊所處理的URI。 使用這個標記,可以把某些遠程成分映射到本地服務器名稱空間, 從而增強了ProxyPass指令的功能。
注意: 要使用這個功能,代理模塊必須編譯在Apache服務器中。 如果你不能確定,可以檢查“httpd -l''的輸出中是否有mod_proxy.c。 如果有,則mod_rewrite可以使用這個功能; 如果沒有,則必須啟用mod_proxy並重新編譯“httpd''程序。
last|L (最後一個規則 last)
立即停止重寫操作,並不再應用其他重寫規則。 它對應於Perl中的last命令或C語言中的break命令。 這個標記可以阻止當前已被重寫的URL為其後繼的規則所重寫。 舉例,使用它可以重寫根路徑的URL('/')為實際存在的URL, 比如, '/e/www/'.
next|N (重新執行 next round)
重新執行重寫操作(從第一個規則重新開始). 這時再次進行處理的URL已經不是原始的URL了,而是經最後一個重寫規則處理的URL。 它對應於Perl中的next命令或C語言中的continue命令。 此標記可以重新開始重寫操作,即, 立即回到循環的頭部。
但是要小心,不要製造死循環!
但是要小心,不要製造死循環!
chain|C (與下一個規則相鏈接 chained)
此標記使當前規則與下一個(其本身又可以與其後繼規則相鏈接的, 並可以如此反複的)規則相鏈接。 它產生這樣一個效果: 如果一個規則被匹配,通常會繼續處理其後繼規則, 即,這個標記不起作用;如果規則不能被匹配, 則其後繼的鏈接的規則會被忽略。比如,在執行一個外部重定向時, 對一個目錄級規則集,你可能需要刪除“.www'' (此處不應該出現“.www''的)。
type|T=MIME-type(強製MIME類型 type)
強製目標文件的MIME類型為MIME-type。 比如,它可以用於模擬mod_alias中的ScriptAlias指令, 以內部地強製被映射目錄中的所有文件的MIME類型為“application/x-httpd-cgi”。
nosubreq|NS (僅用於不對內部子請求進行處理 no internal sub-request)
在當前請求是一個內部子請求時,此標記強製重寫引擎跳過該重寫規則。 比如,在mod_include試圖搜索可能的目錄默認文件(index.xxx)時, Apache會內部地產生子請求。對子請求,它不一定有用的,而且如果整個規則集都起作用, 它甚至可能會引發錯誤。所以,可以用這個標記來排除某些規則。
根據你的需要遵循以下原則: 如果你使用了有CGI腳本的URL前綴,以強製它們由CGI腳本處理, 而對子請求處理的出錯率(或者開銷)很高,在這種情況下,可以使用這個標記。
nocase|NC (忽略大小寫 no case)
它使Pattern忽略大小寫,即, 在Pattern與當前URL匹配時,'A-Z' 和'a-z'沒有區別。
qsappend|QSA (追加請求串 query string append)
此標記強製重寫引擎在已有的替換串中追加一個請求串,而不是簡單的替換。 如果需要通過重寫規則在請求串中增加信息,就可以使用這個標記。
noescape|NE (在輸出中不對URI作轉義 no URI escaping)
此標記阻止mod_rewrite對重寫結果應用常規的URI轉義規則。 一般情況下,特殊字符(如'%', '$', ';'等)會被轉義為等值的十六進製編碼。 此標記可以阻止這樣的轉義,以允許百分號等符號出現在輸出中,如:
RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] 可以使'/foo/zed'轉向到一個安全的請求'/bar?arg=P1=zed'.
passthrough|PT (移交給下一個處理器 pass through)
此標記強製重寫引擎將內部結構request_rec中的uri字段設置為 filename字段的值,它隻是一個小修改,使之能對來自其他URI到文件名翻譯器的 Alias,ScriptAlias, Redirect 等指令的輸出進行後續處理。舉一個能說明其含義的例子: 如果要通過mod_rewrite的重寫引擎重寫/abc為/def, 然後通過mod_alias使/def轉變為/ghi,可以這樣:
RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi
如果省略了PT標記,雖然mod_rewrite運作正常, 即, 作為一個使用API的URI到文件名翻譯器, 它可以重寫uri=/abc/…為filename=/def/…, 但是,後續的mod_alias在試圖作URI到文件名的翻譯時,則會失效。
注意: 如果需要混合使用不同的包含URI到文件名翻譯器的模塊時, 就必須使用這個標記。。 混合使用mod_alias和mod_rewrite就是個典型的例子。
For Apache hackers
如果當前Apache API除了URI到文件名hook之外,還有一個文件名到文件名的hook, 就不需要這個標記了! 但是,如果沒有這樣一個hook,則此標記是唯一的解決方案。 Apache Group討論過這個問題,並在Apache 2.0 版本中會增加這樣一個hook。
skip|S=num (跳過後繼的規則 skip)
此標記強製重寫引擎跳過當前匹配規則後繼的num個規則。 它可以實現一個偽if-then-else的構造: 最後一個規則是then從句,而被跳過的skip=N個規則是else從句. (它和'chain|C'標記是不同的!)
env|E=VAR:VAL (設置環境變量 environment variable)
此標記使環境變量VAR的值為VAL, VAL可以包含可擴展的反向引用的正則表達式$N和%N。 此標記可以多次使用以設置多個變量。 這些變量可以在其後許多情況下被間接引用,但通常是在XSSI (via <!–#echo var="VAR"–>) or CGI (如 $ENV{'VAR'})中, 也可以在後繼的RewriteCond指令的pattern中通過%{ENV:VAR}作引用。 使用它可以從URL中剝離並記住一些信息。
cookie|CO=NAME:VAL:domain[:lifetime[:path]] (設置cookie)
它在客戶端瀏覽器上設置一個cookie。 cookie的名稱是NAME,其值是VAL。 domain字段是該cookie的域,比如'.apache.org', 可選的lifetime是cookie生命期的分鍾數, 可選的path是cookie的路徑。
案例:
city_map.txt的內容:
hangzhou 12
beijing 13
1、hangzhou.google.com/tianqi/20090401 跳轉到 www.google.com/service/detail.html?id=tianqi&date=20090401
RewriteMap city-map txt:/etc/httpd/conf.d/map/city_map.txt
RewriteCond %{HTTP_HOST} ^(.+)\.google\.com$
RewriteRule ^/([\w]+)/([\d]+)$ /service/detail\.html\?id=$1&date=$2&c=${city-map:%1|%1} [PT,L]
解釋:
%{HTTP_HOST}:取請求的域名
^(.+)\.google\.com$:^,開頭;$結尾。.(逗號),除終止符外的任意字符。+,重複一個或一個以上的字符。\,轉義字符。
^/([\w]+)/([\d]+)$:[],集合字符。\w,數字或字母。\d,數字。
$1:表示的是符合RewriteRule 中[\w]+正則式的字符串,也就是tianqi。
$2:表示的是符合RewriteRule 中[\d]+ 正則式的字符串,也就是20090401。
%1:表示的是符合RewriteCond 中.+正則式的字符串,也就是hangzhou。
${city-map:%1|%1}:表示取city-map中%1也就是hangzhou對應的值,如果沒有則為%1也就是hangzhou。
2、能看出下麵的規則是做了什麼嗎?
RewriteCond %{HTTP_HOST} ^(.+)\.google\.com$
RewriteRule ^/([\w]+)/([^-]+)-([^-]+)--([^-]+)-([^-]+)--([^-]+)-([^-]+)--([^-]+-[^-]+--[^-]+-[^-]+--[^-]+-[^-]+)$ /$1/$2=$3&$4=$5&$6=$7&$8 [C]
RewriteCond %{HTTP_HOST} ^(.+)\.google\.com$
RewriteRule ^/([\w]+)/([^-]+)-([^-]+)--([^-]+)-([^-]+)--([^-]+)-([^-]+)$ /service/list\.html\?frontCategoryId=${category-map:$1|0}&$2=$3&$4=$5&$6=$7&city=${city-map:%1|%1} [PT,L]
解釋:
這個規則是想把-(中劃線)轉為=,把- -(兩條中劃線)轉為&。
[^-]:^在字符集合符號([])之內表示反向選擇,之外表示行首,所以表示不以-開頭。
因為$N,N最大為9,所以使用了C,用第二條RewriteRule把第一條RewriteRule中的最後一個節點,即$8,進行繼續轉換。
此外,rewrite規則中如果遇到中文,相當有可能會出現亂碼問題,因為apache在rewrite時會做一次url解碼,這時jk進行請求轉發時,就不會再是編碼後的字符串了。此種情況,可以在一開始就進行兩次編碼(encode),或者在接收請求時先用ISO-8859-1取字節流,再使用UFT-8來new String。(new String(str.getBytes("ISO-8859-1"),"UFT-8"))
rewrite規則路徑:/etc/httpd/conf.d/
本文版权:http://www.ndfweb.cn/news-540.html