У меня проблемы с правилами Apache mod_rewrite. Всякий раз, когда я пытаюсь пойти https://example.com//
(см. двойную косую черту в конце) он перенаправляет на страницу 301, но добавляет местоположение каталога, т.е. https://example.com/var/www/my-domain.com/html
что нежелательно.
Вот мой .htaccess
файл:
ErrorDocument 404 /views/pages/404.php
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{THE_REQUEST} \s/+(.*?)/+(/\S+) [NC]
RewriteRule ^(.*) [L,R=404]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/{2,} [NC]
RewriteRule ^(.*) $1 [R=301,L]
RewriteRule ^contact-us/?$ views/pages/contact.php [NC,L]
То же самое происходит, когда я иду в https://example.com//contact-us
https://example.com/contact-us//
хорошо перенаправляется на https://example.com/contact-us
и https://example.com//contact-uss
хорошо перенаправляется на страницу 404.
Если вам нужна дополнительная информация, дайте мне знать.
Скопировано с мой ответ на StackOverflow на тот же вопрос:
https://stackoverflow.com/questions/53236444/mod-rewrite-is-adding-var-www-to-the-resulting-url
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/{2,} [NC] RewriteRule ^(.*) $1 [R=301,L]
Вам не хватает префикса косой черты на замена. Это приводит к замене относительного пути (поскольку $1
обратная ссылка не содержит префикса косой черты), к которому mod_rewrite ставит префикс каталога-префикса (т.е. /var/www/example.com/html
). Это приведет к искаженному перенаправлению, которое вы видите. В RewriteRule
следует записать как:
RewriteRule (.*) /$1 [R=301,L]
(The ^
якорь на RewriteRule
шаблон здесь не требуется.)
Однако следующее перенаправление также недопустимо:
RewriteCond %{THE_REQUEST} \s/+(.*?)/+(/\S+) [NC] RewriteRule ^(.*) [L,R=404]
Вам не хватает замена аргумент в целом. [L,R=404]
будет рассматриваться как замена строка (не флаги, как предполагалось). Это также приведет к неправильной перезаписи / перенаправлению. В RewriteRule
следует записать как:
RewriteRule (.*) - [R=404]
Обратите внимание -
(одинарный дефис) используется как замена аргумент (который позже игнорируется). При указании кода ответа, отличного от 3xx, L
подразумевается флаг.
Однако мне любопытно, что вы здесь пытаетесь сделать, поскольку вы, кажется, "принимаете" несколько косых черт в одной директиве ( сокращение их), но затем отклонить несколько косых черт в другой директиве (с 404)? Почему бы не сократить все последовательности множественных косых черт везде, где они встречаются в URL-пути?
Например, замените следующий (измененный код):
# Remove trailing slash from URL (except files and directories)
# >>> Why files? Files don't normally have trailing slashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Reject multiple slashes later in the URL or 3+ slashes at the start of the URL
RewriteCond %{THE_REQUEST} \s/+(.*?)/+(/\S+) [NC]
RewriteRule (.*) - [R=404]
# Reduce multiple slashes at the start of the URL
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/{2,} [NC]
RewriteRule (.*) /$1 [R=301,L]
Примерно так (в зависимости от требований):
# Reduce sequences of multiple slashes to a single slash in the URL-path
# NB: This won't work to reduce slashes in the query string (if that is an issue)
RewriteCond %{THE_REQUEST} \s[^?]*//+
RewriteRule (.*) /$1 [R=302,L]
# Remove trailing slash from URL (except directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=302,L]
Обратите внимание, что я изменил директивы так, чтобы косые черты были уменьшены до того, как будет удалена последняя косая черта.
Обратите внимание, что регулярное выражение \s[^?]*//+
специально проверяет наличие нескольких косых черт только в URL-пути, исключая строку запроса. Это важно, если несколько слэшей могут законно происходят в Строка запроса, поскольку RewriteRule
Директива только уменьшает количество косых черт в URL-пути. В противном случае вы получите цикл перенаправления.
Протестируйте с 302, чтобы избежать проблем с кешированием. И очистите кеш браузера перед тестированием.