Редирект на другой домен - где ставить правило и почему оно не работает
Настраиваем постоянный редирект на новый домен и разбираемся, почему правило не срабатывает или срабатывает не полностью.
Решение
Ставим правило в nginx отдельным серверным блоком:
server { listen 80; server_name old-domain.ru www.old-domain.ru; return 301 https://new-domain.ru$request_uri; # адрес страницы сохраняется # оба написания имени, с www и без, склеивают одним блоком}Отдельный блок надёжнее условия внутри рабочего: он не участвует в обработке живого сайта и не задевает его правила. В окружении такой блок кладут отдельным файлом в каталог подключаемых конфигов.
Меняем адрес сайта в настройках платформы:
// Настройки - Настройки продукта - Сайты - параметры сайта$site = new CSite();$site->Update($siteId, ['SERVER_NAME' => 'new-domain.ru']);// адрес отсюда идёт в письма и в абсолютные ссылки, а не из строки браузераБез этой правки платформа продолжит собирать абсолютные ссылки и письма со старым доменом. Редирект их подхватит, но покупатель увидит в письме прежний адрес, а поисковик - цепочку перенаправлений.
Проверяем, что отвечает сервер:
curl -sI http://old-domain.ru/catalog/ | head -3curl -sI https://new-domain.ru/catalog/ | head -3В первом ответе должен быть код 301 и заголовок с новым адресом, во втором - 200. Цепочка из двух и более перенаправлений означает, что правило дублируется на разных уровнях.
Сбрасываем кеш композита:
// закешированные страницы хранят абсолютные ссылки со старым доменомCHTMLPagesCache::getInstance()->deleteAll();BXClearCache(true);Композитный кеш переживает правку конфигов: страницы отдаются из файлов до первого сброса. Именно поэтому часть сайта после смены домена ещё какое-то время уводит на старый адрес.
Ищем оставшиеся абсолютные ссылки в контенте:
SELECT ID, NAME FROM b_iblock_elementWHERE DETAIL_TEXT LIKE '%old-domain.ru%' OR PREVIEW_TEXT LIKE '%old-domain.ru%'LIMIT 50;Редирект такие ссылки подхватит, но каждая даст лишний переход. На большом каталоге их переписывают запросом, предварительно сняв резервную копию таблицы.
Ставим редирект с IP-адреса на домен:
server { listen 80 default_server; # ловит всё, что не совпало по имени server_name _; return 301 https://new-domain.ru$request_uri;}Блок по умолчанию заодно закрывает обращения по чужому домену, направленному на этот сервер: без него сайт открывается по любому имени, указывающему на его IP.
Порядок работ при переезде получается такой: правило в nginx, адрес сайта в настройках, сброс кеша, замена абсолютных ссылок в контенте. Пропуск любого шага даёт свой набор жалоб, и по симптому легко понять, какой именно шаг забыт.
Типичные проблемы
Правило редиректа из админки не срабатывает.
Его перехватывает nginx или .htaccess: они отрабатывают раньше кода платформы. Проверяют сверху вниз, начиная с конфига веб-сервера.
Часть страниц уходит на старый домен после смены.
Старый адрес остался в настройках сайта либо в закешированных страницах композита. Правка конфига ни то, ни другое не задевает.
Браузер показывает цепочку из нескольких редиректов.
Одно и то же правило прописано и в nginx, и в .htaccess. Оставляют один уровень: лишние перенаправления замедляют ответ и портят индексацию.
Редирект с домена в национальной зоне не работает.
Кириллический домен приходит в кодировке punycode. В конфиге сервера его пишут в этом виде, а не буквами.
Статика на старом домене продолжает отдаваться.
nginx отдаёт существующие файлы сам, не заглядывая в правила приложения. Для статики правило нужно в самом nginx.
Частые вопросы
На каком уровне ставить редирект?
Постоянный редирект целого домена - в nginx: он отрабатывает первым и не тратит PHP. Точечные правила по отдельным адресам удобнее вести в платформе: их видно в админке и они переживают перенос сервера.
Чем 301 отличается от 302 при смене домена?
Первый говорит поисковику, что переезд постоянный, и вес страницы передаётся новому адресу. Второй означает временный переезд, и старый адрес остаётся в индексе.
Как перенаправить с IP-адреса на домен?
Отдельным серверным блоком по умолчанию: он ловит запросы, у которых имя не совпало ни с одним настроенным доменом. Заодно закрывает обращение к сайту по чужому домену, направленному на этот сервер.
Нужно ли что-то делать со ссылками внутри контента?
Абсолютные ссылки на старый домен стоит переписать: редирект их подхватит, но каждая даёт лишний переход. Ищут прямым запросом по таблицам контента.
Смежное
- nginx и PHP-FPM - оглавление подтемы
- ERR_TOO_MANY_REDIRECTS: слишком много перенаправлений - когда переезд уходит в цикл
- BitrixVM и веб-окружение - кто генерирует конфиги веб-сервера
- Смена домена сайта: настройки, куки, защита, редиректы - что ещё меняют вместе с доменом
- Сервер и поиск - устройство сервера целиком
- Ошибки сервера и базы данных - кто отдаёт коды 500 и 502
- nginx и PHP-FPM: статика, пулы, медленные ответы - как связка обслуживает запросы
- Экспорт каталога на торговые площадки: фид, адреса, поля - где ещё всплывает старый домен
- Редиректы внутри сайта: 301 на раздел, https и старые адреса - переходы внутри одного сайта