Apache-2.4

RewriteCond 中的 RewriteMap 不起作用(Apache)

  • September 30, 2020

我有一個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}

這不起作用,因為CondPatternRewriteCond指令的第二個參數)是一個正則表達式,因此不支持變數擴展。(就像您不能使用表單$n%n伺服器變數%(SERVER_VAR}或環境變數%{ENV:MY_ENV_VAR}等的反向引用一樣。)否則它會與 PCRE 正則表達式語法衝突。只有TestStringRewriteCond指令的第一個參數)和RewriteRule 替換參數支持變數擴展,因為這些參數是“正常”字元串,而不是正則表達式。

但是,您仍然可以執行所需的操作並檢查從 . 返回的正確版本號RewriteMap是否存在於查詢字元串的開頭。相反,擴展TestStringRewriteMap中的結果(它支持變數擴展,因為這是一個“普通”字元串,而不是正則表達式)並使用內部反向引用進行比較。

例如,將 更改RewriteCond為:

RewriteCond %{QUERY_STRING}@${versions:version} !^v=([\d.]+)(?:&[^@]*)?@\1

在變數擴展之後,我們最終將表單的字元串v=0.5@0.7與 regex匹配^v=([\d.]+)(?:&.*)?@\1\1是對第一個擷取的子模式的內部反向引用(即vURL 參數的值)。因此,這有效地將 URL 參數值與從RewriteMap. 然後整個表達式被否定!前綴)所以當條件不匹配時它是成功的*,*即。版本號不同。

([\d.]+)- 匹配查詢字元串中的版本號,它由 1 個或多個數字或文字點組成。例如。0.5

(?:&.*)?- 匹配查詢字元串的其餘部分(如果有)。

@只是查詢字元串或“版本”字元串中不會出現的任意字元串。

您不需要將參數括在雙引號中,除非它們包含空格(即使這樣,您也可以使用反斜杠轉義空格)。因此,在此範例中,雙引號完全是可選的。這同樣適用於RewriteRule指令。

引用自:https://serverfault.com/questions/1035680