Назад | Перейти на главную страницу

С 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 для /folder и все же перенаправить весь трафик из этой папки в корень.

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

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

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

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

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

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

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

смешивание RedirectMatch и RewriteRule не смогли

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