Мне нужно перенаправить все запросы от
https://example.com/*
на https://example.com/test/*
, если URL-адрес не содержит подстроки test
.
Пока у меня есть эти правила перезаписи
RewriteBase /
RewriteCond %{THE_REQUEST} !^/test
RewriteRule ^/?$ /test/$1 [R=301,L] # if the url does not contain test, redirect to url with test
RewriteCond %{THE_REQUEST}% test
RewriteRule ^test?(.*)$ /$1 [L] # mask the fact that the url is not https://example.com/ and instead is https://example.com/test but apache serve the website like if it was on root
Если я обращаюсь к https://example.com
, он перенаправляется на https://example.com/test
, но дает бесконечный цикл из-за второго правила.
Как я могу это объединить, чтобы запрос на https://example.com/test*
не перенаправлялся, но запросы на https://example.com/*
обходились без изменения корневого каталога www, и поэтому он будет работать для всех URL-адресов.
Обновлено:
The test should be in url (for user experience), but the apache should route like if it was not in url and instead the request came to root url, so application routing is preserved internally without having to change the app itself.
Ах хорошо. Однако вы должны ссылаться на URL-адреса /test
в своем приложении (поэтому вам все равно нужно «изменить приложение», несмотря на ваш последний комментарий), иначе /test
на самом деле не находится в URL-адресах, которые пользователи и поисковые системы видят на странице. (они будут перенаправлен), и ваши пользователи будут получать внешнее перенаправление каждый раз, когда они нажимают на одну из ваших ссылок (плохо для SEO и взаимодействия с пользователем).
«Перенаправление», реализованное в .htaccess
для префикса «старых» URL-адресов с помощью /test
, предназначено только для SEO — как и при любом изменении URL-адреса «старый» на «новый». (Не требуется, чтобы ваше приложение функционировало с /test
в URL-пути, поскольку ваши внутренние URL-адреса уже должны включать /test
.)
Вместо этого попробуйте так:
RewriteEngine On
# Insert "/test" at the start of the URL-path if absent in "direct" requests
RewriteRule %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^test/ /test/$1 [R=301,L]
# Rewrite "/test" URLs back to root
RewriteRule ^test(?:$|/(.*)) /$1 [L]
Переменная среды REDIRECT_STATUS
используется для предотвращения цикла перенаправления. Он пуст при первоначальном запросе от клиента и устанавливается в статус ответа HTTP после перезаписи (ниже).
Сначала проверьте с 302 (временной) переадресацией и меняйте на 301 (постоянную) только тогда, когда вы уверены, что это работает так, как задумано.
Перед тестированием вам необходимо очистить кеш браузера.
@TheLaw Это заменяет все ваших правил. Однако... при втором прочтении вашего вопроса кажется, что вы хотите «замаскировать» подкаталог /test
, поэтому вам не следует в первую очередь реализовывать перенаправление, а /test
не должно быть в URL-адресе?
Тест должен быть в URL-адресе (для удобства пользователя), но apache должен маршрутизировать, как если бы он не был в URL-адресе, а вместо этого запрос пришел к корневому URL-адресу, поэтому маршрутизация приложения сохраняется внутри, без необходимости изменять само приложение.
@TheLaw Ах, хорошо, это кажется противоположностью (более распространенной) маскировке каталогов? «без необходимости изменять само приложение» — хотя вам все равно нужно изменить приложение, чтобы включить /test
во внутренние URL-адреса — вы не должны полагаться на .htaccess
, если это то, что вы подразумеваете. Я обновил свой ответ.
Ваше решение почти то, что я искал, но затем я сломал css и ссылки, поэтому вместо этого я выбрал гибридное решение, где я буду использовать второй исходный редирект, чтобы замаскировать тест в URL-адресе, а затем обработать 301 в приложении через заголовок модификация, если тест не находится в URL. Закрытие этого вопроса и пометка вашего ответа как правильного, так как вы потратили время на ответ
@TheLaw «но потом я сломал css и ссылки» - это может быть результатом использования относительных URL-адресов для ваших статических ресурсов (и в ваших ссылках) - поскольку вы перенаправляете на другую глубину пути. См. мой ответ на следующий вопрос StackOverflow: Проблемы с рендерингом JS и CSS после правила перезаписи URL-адреса файла .htaccess
Спасибо за ответ, но это не работает, я все равно получаю бесконечное перенаправление из-за второго правила перезаписи, которое я должен соблюдать, чтобы приложение работало.