. У меня есть 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]
Это не ' t
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(2-й аргумент директивы RewriteCond
)является регулярным выражением и, следовательно, не поддерживает раскрытие переменных. (Так же, как вы не можете использовать обратные ссылки в форме $n
или %n
, или серверные переменные %(SERVER_VAR}
, или env vars %{ENV:MY_ENV_VAR}
и т. д. )В противном случае это будет конфликтовать с синтаксисом регулярных выражений PCRE. Только первый аргумент TestString(директивы RewriteCond
)и аргументыRewriteRule
подстановки поддерживают раскрытие переменных, поскольку эти аргументы являются «обычными» строками, а не регулярными выражениями.
Тем не менее, вы все равно можете сделать то, что вам нужно, и проверить, что правильный номер версии, возвращенный из RewriteMap
, присутствует в начале строки запроса. Вместо этого расширьте результат RewriteMap
в TestString (, который поддерживает раскрытие переменных, поскольку это «обычная» строка, а не регулярное выражение )и , сравните это с использованием внутренняя обратная ссылка.
Например, замените RewriteCond
на:
RewriteCond %{QUERY_STRING}@${versions:version} !^v=([\d.]+)(?:&[^@]*)?@\1
После раскрытия переменной мы получим соответствие строки вида v=0.5@0.7
регулярному выражению ^v=([\d.]+)(?:&.*)?@\1
. \1
является внутренней обратной ссылкой на первый захваченный подшаблон (, т.е. значение параметра URL v
). Таким образом, это эффективно сопоставляет значение параметра URL со значением, возвращаемым из RewriteMap
. Все это выражение затем инвертируется(!
префиксом), поэтому оно считается успешным, когда условие не соответствует, т.е. номер версии другой.
([\d.]+)
-Соответствует номеру версии в строке запроса, состоящей из 1 или более цифр или буквенных точек.например.0.5
(?:&.*)?
-Соответствует остатку строки запроса (, если есть).
@
— это просто произвольная строка, которая иначе не встречается в строке запроса или строке «версия».
Вам не нужно заключать аргументы в двойные-кавычки, если только они не содержат пробелов (, даже в этом случае вместо пробелов можно использовать обратную косую черту). Таким образом, двойные кавычки в этом примере совершенно необязательны. То же самое относится и к директиве RewriteRule
.