RewriteCond 中的 RewriteMap 不起作用(Apache)
我有一個
RewriteCond
檢查是否{QUERY_STRING}
包含正確的版本號,如果沒有,則將使用者重定向到正確的版本。例如,如果 v0.7 是最新的,
http://localhost/?v=0.5
則應將訪問的使用者重定向到,http://localhost/?v=0.7
但由於某種原因,如果RewriteMap
在條件下使用,它不起作用…這有效
RewriteMap versions txt:/var/www/html/version.txt RewriteCond "%{QUERY_STRING}" !^v=0.7 RewriteRule "^/$" "/?v=${versions:version}" [R,L]
這不
RewriteMap versions txt:/var/www/html/version.txt RewriteCond "%{QUERY_STRING}" !^v=${versions:version} RewriteRule "^/$" "/?v=${versions:version}" [R,L]
version.txt 的內容
## ## version.txt -- rewriting map ## The version number written here will be mapped to the URL ## ## version 0.7
RewriteCond "%{QUERY_STRING}" !^v=${versions:version}
這不起作用,因為CondPattern(
RewriteCond
指令的第二個參數)是一個正則表達式,因此不支持變數擴展。(就像您不能使用表單$n
或%n
伺服器變數%(SERVER_VAR}
或環境變數%{ENV:MY_ENV_VAR}
等的反向引用一樣。)否則它會與 PCRE 正則表達式語法衝突。只有TestString(RewriteCond
指令的第一個參數)和RewriteRule
替換參數支持變數擴展,因為這些參數是“正常”字元串,而不是正則表達式。但是,您仍然可以執行所需的操作並檢查從 . 返回的正確版本號
RewriteMap
是否存在於查詢字元串的開頭。相反,擴展TestStringRewriteMap
中的結果(它支持變數擴展,因為這是一個“普通”字元串,而不是正則表達式)並使用內部反向引用進行比較。例如,將 更改
RewriteCond
為:RewriteCond %{QUERY_STRING}@${versions:version} !^v=([\d.]+)(?:&[^@]*)?@\1
在變數擴展之後,我們最終將表單的字元串
v=0.5@0.7
與 regex匹配^v=([\d.]+)(?:&.*)?@\1
。\1
是對第一個擷取的子模式的內部反向引用(即v
URL 參數的值)。因此,這有效地將 URL 參數值與從RewriteMap
. 然後整個表達式被否定(!
前綴)所以當條件不匹配時它是成功的*,*即。版本號不同。
([\d.]+)
- 匹配查詢字元串中的版本號,它由 1 個或多個數字或文字點組成。例如。0.5
(?:&.*)?
- 匹配查詢字元串的其餘部分(如果有)。
@
只是查詢字元串或“版本”字元串中不會出現的任意字元串。您不需要將參數括在雙引號中,除非它們包含空格(即使這樣,您也可以使用反斜杠轉義空格)。因此,在此範例中,雙引號完全是可選的。這同樣適用於
RewriteRule
指令。