apache 模組mod_rewrite 提供了一個基於Regex分析器的重寫引擎來即時重寫URL請求。 它支援每個完整規則可以擁有不限數量的子規則以及附加條件規則的靈活而且強大的URL操作機制。 此URL操作可以依賴於各種測試,比如伺服器變數、環境變數、HTTP頭、時間標記,甚至各種格式的用於匹配URL組成部分的尋找資料庫。
此模組可以操作URL的所有部分(包括路徑資訊部分),在伺服器級的(httpd.conf)和目錄級的(. htaccess )配置都有效,還可以產生最終請求字串。 此重寫操作的結果可以是內部子處理,也可以是外部請求的轉向,甚至還可以是內部代理處理。
這裡著重介紹一下RewriteCond 的規則以及參數說明。RewriteCond指令定義了規則生效的條件,即在一個RewriteRule指令之前可以有一個或多個RewriteCond指令。 條件之後的重寫規則僅在當前URI與Pattern匹配並且滿足此處的條件(TestString能夠與CondPattern匹配)時才會起作用。
【說明】定義重寫發生的條件
【文法】RewriteCond TestString CondPattern [flags]
【範圍】server config, virtual host, directory, .htaccess
【覆蓋項】FileInfo
【狀態】 擴充(E)
【模組】mod_rewrite
TestString是一個純文字的字串,但是還可以包含下列可擴充的成分:
RewriteRule反向引用 ,引用方法是:$N (0 <= N <= 9)引用當前(帶有若干RewriteRule指令的)RewriteCond中的與Pattern匹配的分組成分(圓括弧!)。
RewriteCond反向引用 ,引用方法是:%N (1 <= N <= 9)引用當前若干RewriteCond條件中最後符合的條件中的分組成分(圓括弧!)。
RewriteMap擴充 ,引用方法是:${mapname:key|default} 細節請參見RewriteMap指令 。
伺服器變數 ,引用方法是:%{NAME_OF_VARIABLE} NAME_OF_VARIABLE可以是下表列出的字串之一:
HTTP頭串連與請求
HTTP_USER_AGENT
HTTP_REFERER
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_ACCEPT REMOTE_ADDR
REMOTE_HOST
REMOTE_PORT
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
PATH_INFO
QUERY_STRING
AUTH_TYPE
伺服器自身 日期和時間 其它
DOCUMENT_ROOT
SERVER_ADMIN
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME API_VERSION
THE_REQUEST
REQUEST_URI
REQUEST_FILENAME
IS_SUBREQ
HTTPS
這些變數都對應於類似命名的HTTP MIME頭、Apache伺服器的C變數、Unix系統中的struct tm欄位,其中的大多數在其他的手冊或者CGI規範中都有說明。 其中為mod_rewrite所特有的變數如下:
IS_SUBREQ
如果正在處理的請求是一個子請求,它將包含字串”true”,否則就是”false”。 模組為瞭解析URI中的附加檔案,可能會產生子請求。
API_VERSION
這是正在使用中的Apache模組API(伺服器和模組之間內部介面)的版本, 其定義位於include/ap_mmn.h中。 此模組API版本對應於正在使用的Apache的版本(比如在Apache 1.3.14的發行版中這個值是19990320:10)。 通常,對它感興趣的是模組的開發人員。
THE_REQUEST
這是由瀏覽器發送的完整的HTTP請求行(比如:”GET /index.html HTTP/1.1″)。 它不包含任何瀏覽器發送的其它頭資訊。
REQUEST_URI
這是在HTTP請求行中所請求的資源(比如上述例子中的”/index.html”)。
REQUEST_FILENAME
這是與請求相匹配的完整的本地檔案系統的檔案路徑名。
HTTPS
如果串連使用了SSL/TLS,它將包含字串”on”,否則就是”off”(無論mod_ssl 是否已經載入,該變數都可以安全的使用)。
其它注意事項:
SCRIPT_FILENAME和REQUEST_FILENAME包含的值是相同的——即Apache伺服器內部的request_rec結構中的filename欄位。 第一個就是大家都知道的CGI變數名,而第二個則是REQUEST_URI(request_rec結構中的uri欄位)的一個副本。
特殊形式:%{ENV:variable} ,其中的variable可以是任意環境變數。 它是通過尋找Apache內部結構或者(如果沒找到的話)由Apache伺服器處理序通過getenv()得到的。
特殊形式:%{SSL:variable} ,其中的variable可以是一個SSL環境變數 的名字,無論mod_ssl 模組是否已經載入都可以使用(未載入時為空白字串)。 比如:%{SSL:SSL_CIPHER_USEKEYSIZE}將會被替換為128。
特殊形式:%{HTTP:header} ,其中的header可以是任意HTTP MIME頭的名稱。 它總是可以通過尋找HTTP請求而得到。 比如:%{HTTP:Proxy-Connection}將被替換為Proxy-Connection:HTTP頭的值。
預設形式:%{LA-U:variable} ,variable的最終值在執行一個內部(基於URL的)子請求後確定。 當需要使用一個目前未知但是會在之後的過程中設定的變數的時候,就可以使用這個方法。 例如,需要在伺服器級配置(httpd.conf檔案)中根據REMOTE_USER變數進行重寫, 就必須使用%{LA-U:REMOTE_USER}。 因為此變數是由URL重寫(mod??_rewrite)步驟之後的認證步驟設定的。 但是另一方面,因為mod_rewrite是通過API修正步驟來實現目錄級(.htaccess檔案)配置的, 而認證步驟先於API修正步驟,所以可以用%{REMOTE_USER}。
預設形式:%{LA-F:variable} ,variable的最終值在執行一個內部(基於檔案名稱的)子請求後確定。 大多數情況下和上述的LA-U是相同的。
CondPattern是條件模式,即一個應用於當前TestString執行個體的Regex。TestString將被首先計算,然後再與CondPattern匹配。
注意:CondPattern是一個perl相容的Regex,但是還有若干增補:
1、可以在CondPattern串的開頭使用’!'(驚歎號)來指定 不匹配 。
2、CondPatterns有若干特殊的變種。 除了Regex的標準用法,還有下列用法:
‘<CondPattern ‘(詞典順序的小於)
將CondPattern視為純字串,與TestString按詞典順序進行比較。 如果TestString小於CondPattern則為真。
‘>CondPattern ‘(詞典順序的大於)
將CondPattern視為純字串,與TestString按詞典順序進行比較。 如果TestString大於CondPattern則為真。
‘=CondPattern ‘(詞典順序的等於)
將CondPattern視為純字串,與TestString按詞典順序進行比較。 如果TestString等於CondPattern(兩個字串逐個字元地完全相等)則為真。 如果CondPattern是”"(兩個雙引號),則TestString將與Null 字元串進行比較。
‘-d ‘(目錄)
將TestString視為一個路徑名並測試它是否為一個存在的目錄。
‘-f ‘(常規檔案)
將TestString視為一個路徑名並測試它是否為一個存在的常規檔案。
‘-s ‘(非空的常規檔案)
將TestString視為一個路徑名並測試它是否為一個存在的、尺寸大於0的常規檔案。
‘-l ‘(符號串連)
將TestString視為一個路徑名並測試它是否為一個存在的符號串連。
‘-x ‘(可執行)
將TestString視為一個路徑名並測試它是否為一個存在的、具有可執行許可權的檔案。 該許可權由作業系統檢測。
‘-F ‘(對子請求存在的檔案)
檢查TestString是否為一個有效檔案,而且可以在伺服器當前的存取控制配置下被訪問。 它使用一個內部子請求來做檢查,由於會降低伺服器的效能,所以請謹慎使用!
‘-U ‘(對子請求存在的URL)
檢查TestString是否為一個有效URL,而且可以在伺服器當前的存取控制配置下被訪問。 它使用一個內部子請求來做檢查,由於會降低伺服器的效能,所以請謹慎使用!
注意: 所有這些測試都可以用驚歎號作首碼(‘!’)以實現測試條件的反轉。
3、還可以在CondPattern之後追加特殊的標記[flags] 作為RewriteCond指令的第三個參數。flags是一個以逗號分隔的以下標記的列表:
‘nocase|NC ‘(忽略大小寫)
它使測試忽略大小寫,擴充後的TestString和CondPattern中’AZ’ 和’a-z’是沒有區別的。 此標記僅用於TestString和CondPattern的比較,而對檔案系統和子請求的檢查不起作用。
‘ornext|OR ‘(或下一條件)
它以OR方式組合若干規則的條件,而不是隱含的AND。 典型的例子如下:
RewriteCond %{REMOTE_HOST} ^host1.* [OR]
RewriteCond %{REMOTE_HOST} ^host2.* [OR]
RewriteCond %{REMOTE_HOST} ^host3.*
RewriteRule …針對這3個主機的規則集…如果不用這個標記,你就必須要書寫三次條件/規則對。
舉例
如果要按要求標頭中的”User-Agent:”重寫一個網站的首頁,可以這樣寫:
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 ]
解釋:
如果你使用的瀏覽器識別標誌是’Mozilla’,則你將得到內容最大化的首頁(含有Frames等等)。
如果你使用的是(基於終端的)Lynx, 則你得到的是內容最小化的首頁(不含table等等)。
如果上述條件都不滿足(使用的是其他瀏覽器),則你得到的是一個標準的首頁。
摘自 第零空間