Mod_rewrite добавляет / var / www к полученному URL - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть некоторые проблемы с правилами 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.

Если кому-то понадобится дополнительная информация, дайте мне знать.

1 Ответ

0 голосов
/ 11 ноября 2018
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]

(Якорь ^ на шаблоне RewriteRule здесь не нужен.)

Однако следующее перенаправление также недопустимо:

RewriteCond %{THE_REQUEST} \s/+(.*?)/+(/\S+) [NC]
RewriteRule ^(.*) [L,R=404]

Вам не хватает аргумента substitution вообще. [L,R=404] будет рассматриваться как строка подстановки *1026* (а не flags , как предполагалось). Это также приведет к неправильной перезаписи / перенаправлению. RewriteRule должно быть записано как:

RewriteRule (.*) - [R=404]

Обратите внимание, что - (одиночный дефис) используется в качестве аргумента substitution (который позже игнорируется). При указании кода ответа не-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} //+
RewriteRule (.*) /$1 [R=302,L]

# Remove trailing slash from URL (except directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=302,L]

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

Тест с 302, чтобы избежать проблем с кэшированием. И очистите кеш браузера перед тестированием.

ОБНОВЛЕНИЕ: Если двойная косая черта может (законно) произойти в части URL-адреса строка запроса , то приведенное выше приведет к циклу перенаправления, так как условие проверяет наличие нескольких косых черт в любом месте в URL (включая строку запроса), тогда как RewriteRule уменьшает только несколько косых черт в URL-пути. Если вам нужно разрешить несколько косых черт в строке запроса, измените CondPattern с //+ на \s[^?]*//+, чтобы специально проверять только URL-путь, а не весь URL. Другими словами:

RewriteCond %{THE_REQUEST} \s[^?]*//+
RewriteRule (.*) /$1 [R=302,L]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...