RewriteCond 中的 RewriteMap 不起作用(Apache)

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

答案1

RewriteCond "%{QUERY_STRING}" !^v=${versions:version}

这不起作用,因为条件模式(该RewriteCond指令的第二个参数)是正则表达式,因此不支持变量扩展。(就像您不能使用$n%n或服务器变量%(SERVER_VAR}或环境变量形式的反向引用一样%{ENV:MY_ENV_VAR}等形式的反向引用一样。)否则它会与 PCRE 正则表达式语法冲突。只有测试字符串(该指令的第一个参数RewriteCond)和RewriteRule 代换参数支持变量扩展,因为这些参数是“常规”字符串,而不是正则表达式。

但是,您仍然可以执行所需的操作,并检查从 返回的正确版本号是否RewriteMap存在于查询字符串的开头。相反,RewriteMap测试字符串(它支持变量扩展,因为这是一个“普通”字符串,而不是正则表达式)和比较这使用内部反向引用。

例如,将以下RewriteCond内容改为:

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

在变量扩展之后,我们最终将形式为 的字符串[email protected]与正则表达式进行匹配^v=([\d.]+)(?:&.*)?@\1\1是对第一个捕获的子模式(即 URL 参数的值v)的内部反向引用。 因此,这实际上将 URL 参数值与 从 返回的值进行匹配RewriteMap。 然后整个表达式为否定!前缀),所以当条件满足时,它就成功了不是匹配,即版本号不同。

([\d.]+)- 匹配查询字符串中的版本号,该版本号由一个或多个数字或文字点组成。例如。0.5

(?:&.*)?- 匹配查询字符串的其余部分(如果有)。

@只是一个任意字符串,它不会出现在查询字符串或“版本”字符串中。

您不需要用双引号括住参数,除非它们包含空格(即使这样,您也可以使用反斜杠转义空格)。因此,在此示例中,双引号完全是可选的。这同样适用于指令RewriteRule

相关内容