С Apache перезаписывайте трафик на папка и все же перенаправлять весь трафик из этой папки

У меня есть веб-сайт, который в настоящее время переносится со старой CMS на новую (Laravel). Только некоторые языки сайта были перенесены в Laravel. В общем, моя корневая папка vhost имеет что-то вроде этого:

[D] staticContentDirectory1
[D] staticContentDirectory2
...
[D] oldCmsDirectory1
[D] oldCmsDirectory2
...
[D] oldCmsDirectoryN
[D] public
[F] index-of-the-old-cms-still-in-use.php 

У меня есть . htaccess , который перенаправляет все, что не обрабатывается старой CMS или в каталоге статического содержимого, в Laravel и выглядит примерно так:

RewriteRule ^((?!staticContentDirectory1|staticContentDirectory2|public)(.*))$ public/$1 [L]

Существует также общедоступный .htaccess из Laravel

Пока все работает отлично, и мы очень довольны результатом (с учетом начальных ограничений).

Однако мы обнаружили проблему. Каким-то образом Google удалось обнаружить, что / public существует, и просканировать его, что привело к URL-адресу с / public / внутри, который с тех пор создал / public / public / URL-адреса (который, к счастью, возвращает ошибку 500 и позволяет избежать бесконечного количества URL-адресов).

Перед исправлением CMS и robots. txt мы попытались исправить это, переписав / перенаправив трафик с / public на / .

Много чего было перепробовано, было много сбоев, почти все в бесконечном цикле редиректов.

Поскольку кажется, что каждый модуль Apache выполняет свои функции самостоятельно, смешивание RedirectMatch и RewriteRule не удалось. RewriteCond и RewriteRule либо были бесконечным перенаправлением, либо полностью игнорировались.

TL; DR: Я прошу помощи сейчас: как можно создать RewriteRule в / папку и при этом перенаправить весь трафик из этой папки в корень.

3
задан 13 July 2017 в 15:11
1 ответ

Чтобы избежать цикла перенаправления, вам необходимо различать прямой запрос для подкаталога / public и запрос, который был внутренне переписан в подкаталог / public (что и делает ваша директива выше).

Есть несколько способов сделать это. Один из способов - проверить серверную переменную THE_REQUEST , которая содержит заголовок начального запроса (например, GET / public / любой HTTP / 1.1 ) как отправленный от клиента и не изменяется, когда URL-адрес перезаписывается.

Попробуйте следующее ... как правило, внешние перенаправления должны выполняться до внутренних перезаписей, поэтому следующее правило должно быть в верхней части файла .htaccess в / public подкаталог (не файл .htaccess в корне документа):

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /public
RewriteRule (.*) /$1 [R=302,L]

Для любого прямого запроса, запускающего / public / , затем перенаправьте на / <что угодно> . Предыдущая директива RewriteCond гарантирует, что обрабатываются только прямые запросы.

Директива RewriteRule сначала может показаться немного странной (как будто она, возможно, перенаправляет на себя), но это поскольку шаблон RewriteRule соответствует URL-пути за вычетом каталога-префикс того места, где находится файл .htaccess . Таким образом, при запросе / public / обратная ссылка $ 1 захватывает только . Таким образом, выполняется перенаправление обратно на / .

Обратите внимание, что в настоящее время это временное (302) перенаправление. Измените его на 301 , только если вы уверены, что все работает нормально. 301 жестко кэшируются браузером, поэтому при возникновении ошибки тестирование может стать проблематичным.

смешивание RedirectMatch и RewriteRule не удалось

Поскольку директивы принадлежат разным модулям (mod_alias vs mod_rewrite), они выполняются в разное время во время запроса, независимо от их очевидного порядка в файле конфигурации (mod_rewrite обычно запускается первым). Таким образом, смешивание этих директив действительно может привести к конфликтам. Однако RedirectMatch не дает вам контроля, который требуется в этом случае.

3
ответ дан 3 December 2019 в 06:27

Теги

Похожие вопросы