我有一个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]This不
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发布于 2020-09-29 11:37:32
RewriteCond "%{QUERY_STRING}“!^v=${version:version}
这不起作用,因为CondPattern ( RewriteCond指令的第二个参数)是正则表达式,因此不支持变量展开。(就像您不能使用表单$n或%n或服务器变量%(SERVER_VAR}或env、%{ENV:MY_ENV_VAR}等的反向引用一样)否则它将与PCRE regex语法发生冲突。只有TestString ( RewriteCond指令的第一个参数)和RewriteRule替换参数支持变量扩展,因为这些参数是“常规”字符串,而不是正则表达式。
但是,您仍然可以执行所需的操作,并检查从RewriteMap返回的正确版本号是否存在于查询字符串的开头。相反,展开RewriteMap在TestString中的结果(这确实支持变量展开,因为这是一个“普通”字符串,而不是正则表达式),并使用内部反向引用进行比较。
例如,将RewriteCond更改为:
RewriteCond %{QUERY_STRING}@${versions:version} !^v=([\d.]+)(?:&[^@]*)?@\1在变量展开之后,我们将表单v=0.5@0.7的字符串与regex ^v=([\d.]+)(?:&.*)?@\1匹配。\1是对第一个捕获子模式(即。v URL参数的值)。因此,这有效地将URL参数值与从RewriteMap返回的值相匹配。然后整个表达式被否定(!前缀),因此当条件不匹配时,它是成功的。版本号不同。
([\d.]+) -匹配查询字符串中的版本号,该字符串由一个或多个数字或文字点组成。例如:0.5
(?:&.*)? -匹配查询字符串的其余部分(如果有的话)。
@只是一个不存在于查询字符串或“版本”字符串中的任意字符串。
除非参数包含空格,否则不需要用双引号环绕参数(即使这样,也可以反斜杠转义空格)。因此,在本例中,双引号完全是可选的。这同样适用于RewriteRule指令。
https://serverfault.com/questions/1035680
复制相似问题