Почему RewriteRule для «^ // (. *)» (Начинается с двойной косой черты) не перенаправляет на одинарную косую черту?

Aug 17 2020

Используйте это правило перезаписи в контексте vHost. Но он не перезаписывает запросы, которые начинаются с //.*(двойной слэш). Просто обслуживает их /.*(одинарная косая черта) вместо того, чтобы отвечать перенаправлением на/.*

RewriteRule "^//(.*)" "/$1" [R=301,L]

Почему это не работает?

Ответы

2 MrWhite Aug 18 2020 at 06:51
RewriteRule "^//(.*)" "/$1" [R=301,L]

Это никогда не будет совпадать, потому что URL-путь, с которым совпадает RewriteRule шаблон , уже содержит все экземпляры нескольких косых черт, уменьшенных до одного косого черта.

Чтобы перенаправить такие запросы, вы можете использовать эту «функцию» и просто перенаправить «на себя» и THE_REQUESTвместо этого проверить серверную переменную, чтобы определить, присутствовало ли несколько косых черт в начальном запросе. THE_REQUESTявляется первой строкой заголовка запроса и содержит необработанный URL-адрес необработанного запроса (исключая протокол и имя хоста, но включая строку запроса), отправленный от клиента.

Например, чтобы перенаправить все экземпляры нескольких косых черт на одну косую черту по всему URL-пути, а не только в начале, вы можете сделать что-то вроде этого:

RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule (.*) $1 [R=301,L]

Регулярное выражение \s[^?]*//гарантирует, что мы не сопоставим несколько косых черт в части строки запроса URL-адреса (что в противном случае привело бы к циклу перенаправления).


Позволит ли RewriteCond %{THE_REQUEST} ^//нам применить правило перезаписи только к тем, которые начинаются с двойной косой черты, игнорируя все другие случаи двойной косой черты?

Не совсем так, THE_REQUESTсерверная переменная фактически содержит всю первую строку заголовка HTTP-запроса. Другими словами, строка вида:

GET /foo/bar.html HTTP/1.1

Или, GET //foo/bar.html HTTP/1.1если в начале URL-пути стоит двойная косая черта, вам понадобится что-то вроде этого:

RewriteCond %{THE_REQUEST} \s//[^/]
RewriteRule (.*) $1 [R=301,L]

... чтобы уловить все методы запроса. И, в частности, только двойная косая черта, а не тройная косая черта и т.д. только в начале URL-пути.

\s//[^/]- Это пробел (после метода запроса ), за которым следуют две косые черты и что-то другое, кроме косой черты (то есть либо пробел для корня документа, либо какой-либо другой URL-путь).