Редиректы 301 и 302 — штука полезная, но только пока вы не начинаете лепить их где попало. У меня на практике не раз было так: вроде бы “просто перенесли страницу”, а через пару дней получаем петлю редиректов, 404 в логах и минус к индексации в Яндексе и Google. Честно говоря, это типичная история для сайтов на Bitrix, WordPress и даже Laravel, если редиректы настраивает не тот, кто потом будет это сопровождать.
Что такое 301 и 302, и когда какой использовать
Если совсем по-простому: 301 — это постоянный редирект, 302 — временный. Но на деле между ними есть важная практическая разница. 301 говорит поисковикам: “адрес сменился окончательно, перенеси вес и замени URL в индексе”. 302 говорит: “сейчас отправь пользователя сюда, но старый адрес ещё жив, не спеши его выкидывать”.
Я обычно делаю так: если страница реально переехала навсегда, ставлю 301. Если идёт акция, A/B-тест, временная заглушка, технические работы или сезонный лендинг — 302. И вот тут многие ошибаются: ставят 302 “на всякий случай”, а потом удивляются, почему старый URL продолжает ранжироваться. Или наоборот — ставят 301 на временную акцию и ломают структуру сайта после завершения кампании.
На моей практике 301 чаще всего нужен при:
- переезде сайта на новый домен;
- смене структуры URL;
- склейке дублей со слешем и без слеша;
- переводе HTTP на HTTPS;
- переключении www / без www;
- устранении битых старых ссылок после редизайна.
302 я использую заметно реже. И это нормально. Если у вас типовой корпоративный сайт на WordPress 6.5 или Bitrix с PHP 8.2, то в 80% случаев нужен именно 301. А 302 — только когда есть чёткая временная логика. Забудьте про “пусть пока 302 постоит, потом решим”. Это плохая идея.
Если тема редиректов у вас уже всплывала при переезде или смене структуры, посмотрите ещё отдельную статью про 301 при смене URL. Там я разбираю сценарии именно для миграции структуры, а здесь пойдём глубже — к петлям, цепочкам и 404.
Главные ошибки, которые приводят к петлям и 404
Петля редиректов — это когда URL A ведёт на URL B, а URL B возвращает на URL A. Браузер или бот крутится по кругу, пока не сдаётся. В интерфейсе вы видите что-то вроде “ERR_TOO_MANY_REDIRECTS”, а в логах — десятки одинаковых запросов. На деле это почти всегда ошибка в логике правил, а не “глюк сервера”.
404 после редиректа — другая история. Тут старый URL вроде бы обрабатывается правильно, но целевая страница не существует или была удалена. То есть редирект вроде настроен, но ведёт в никуда. И это особенно неприятно после редизайна или миграции с WordPress на Bitrix, когда URL-структура меняется в нескольких местах сразу.
Самые частые причины, которые я видел у клиентов:
- одновременно включён редирект в CMS и на nginx;
- правило на HTTP→HTTPS конфликтует с правилом www→без www;
- редирект ведёт на URL со слешем, а сервер потом перекидывает обратно без слеша;
- в .htaccess и в панели хостинга стоят дублирующиеся правила;
- в WordPress включён плагин Redirection, а ещё и в functions.php прописан redirect;
- в Bitrix включён обработчик на уровне init.php, но старый редирект остался в настройках веб-сервера;
- целевая страница удалена, а 301 на неё оставили “потому что жалко”.
Был случай с интернет-магазином на WordPress 6.4 и WooCommerce. Хозяин магазина решил “сделать красиво” и одновременно настроил редирект со старых категорий в плагине, в .htaccess и в Cloudflare. В итоге 6 цепочек редиректов, 14 URL в ошибках Search Console и провал по PageSpeed не из-за скорости, а из-за лишних запросов и долгой загрузки HTML. Пришлось вычищать всё по слоям: CDN, сервер, CMS, плагин.
Если хотите системно находить такие проблемы, полезно сначала посмотреть чек-лист по исправлению ошибок на сайте и отдельно статью про логи и анализ ошибок. Без логов вы просто гадаете.
Как проверить, куда реально ведёт редирект
Перед настройкой нового правила я всегда сначала проверяю текущее поведение URL. Не “на глаз”, а нормально: curl, devtools, браузерные расширения, логи nginx или Apache. Потому что иногда в админке CMS показывается одно, а сервер отдаёт совсем другое. И это особенно заметно на сайтах с кэшем, CDN и reverse proxy.
Самая простая проверка через терминал:
curl -I https://site.ru/staryy-url/
В ответе смотрите строки HTTP/1.1 301 Moved Permanently или HTTP/1.1 302 Found и заголовок Location:. Если вместо одного перехода вы видите несколько, значит уже есть цепочка. На практике я ещё люблю проверять полный маршрут:
curl -IL https://site.ru/staryy-url/
Ключ -L показывает всю цепочку переходов. Если их больше двух — почти всегда это лишнее. Нормальная схема выглядит так: старый URL → новый URL → 200 OK. Всё. Без лишних прыжков через www, без промежуточного HTTP и без дублирующихся слешей.
Если вы работаете с WordPress, ещё полезно проверить плагины Redirection, Rank Math, Yoast SEO Premium, Really Simple SSL. У меня был клиент, у которого плагин для SSL делал редирект на HTTPS, а SEO-плагин отдельно правил слеши. В результате одна страница открывалась с четырьмя переходами. Для пользователя это раздражает, а для поискового робота — просто лишняя возня.
Для Bitrix обычно смотрю ещё init.php, .htaccess, настройки nginx и агента обновления. Если сайт на Laravel, проверяю middleware, routes/web.php и серверный конфиг. И да, если у вас стоит Cloudflare или другой CDN, проверять нужно ещё и там. Я это отдельной строкой повторю: CDN тоже может подсовывать свой редирект, и вы долго будете искать проблему не там.
curl -IL до и после внесения изменений. Это быстрее, чем вручную щёлкать страницы в браузере и надеяться на удачу.Настройка 301 и 302 в nginx
Если сервер на nginx, я обычно стараюсь делать редиректы именно там. Это быстрее, чище и надёжнее, чем пытаться завести всё через CMS. На PHP 8.1–8.3 это вообще стандартная история: сервер должен отрабатывать базовую логику, а приложение — только исключения.
Самый частый кейс — перенос с HTTP на HTTPS и склейка www / без www. Вот рабочий пример:
server {
listen 80;
server_name site.ru www.site.ru;
return 301 https://site.ru$request_uri;
}
server {
listen 443 ssl http2;
server_name www.site.ru;
return 301 https://site.ru$request_uri;
}
server {
listen 443 ssl http2;
server_name site.ru;
root /var/www/site.ru/public;
index index.php index.html;
# остальная конфигурация...
}
Тут важный момент: сначала обрабатывается HTTP, потом www, и только потом основной HTTPS-хост. Если перепутать порядок или дублировать логику в нескольких server блоках, легко получить петлю. Особенно если ещё включён HSTS, а старый HTTP-домен всё равно остаётся в правилах. Об этом я подробнее писал в материале про HTTPS-редиректы и HSTS.
Для временного редиректа 302 в nginx используется так же просто:
location /promo/ {
return 302 https://site.ru/novaya-aktsiya/;
}
Или на уровне server:
server {
listen 443 ssl http2;
server_name old.site.ru;
return 302 https://site.ru/vremennaya-stranitsa/;
}
Но я честно скажу: если у вас редиректов больше 10–15 штук, руками в nginx это уже неудобно. Тогда лучше делать карту перенаправлений через отдельный include-файл. Например:
include /etc/nginx/redirects/site.ru.conf;
А в самом файле держать только пары старый → новый. Это удобно для поддержки и нормально масштабируется. У одного клиента на Laravel так было почти 800 старых URL после редизайна, и мы без include-файла просто утонули бы в конфиге. Кстати, если сайт сложный, полезно заглянуть в статью про обратный прокси nginx — там много нюансов по маршрутизации запросов.
Настройка 301 и 302 в .htaccess и PHP
Если у вас Apache или shared-hosting, где доступен только .htaccess, то тут тоже всё решается нормально. Главное — не смешивать бездумно правила из разных источников. Я видел конфигурации, где один редирект был в панели хостинга, второй в CMS, третий в .htaccess. И каждый “помогал” как мог.
Базовый 301 в .htaccess выглядит так:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://site.ru/$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.site\.ru$ [NC]
RewriteRule ^(.*)$ https://site.ru/$1 [L,R=301]
Но тут опять есть нюанс: порядок правил критичен. Сначала HTTPS, потом www, либо наоборот — в зависимости от конкретной архитектуры. Если оба редиректа срабатывают раздельно, вы получите цепочку. Лучше сразу сводить всё к одной целевой версии домена за один шаг.
Для отдельной страницы:
Redirect 301 /staryy-razdel/ https://site.ru/novyy-razdel/
Для 302:
Redirect 302 /aktsiya/ https://site.ru/vremennaya-aktsiya/
На PHP редирект тоже делают, но я использую его только если действительно нужно программное условие. Например, если редирект зависит от языка, куки, авторизации или параметров. Вот пример:
<?php
$uri = $_SERVER['REQUEST_URI'];
if ($uri === '/old-page/') {
header('Location: /new-page/', true, 301);
exit;
}
if ($uri === '/promo/') {
header('Location: /promo-2026/', true, 302);
exit;
}
Но это не лучший вариант для массовых редиректов. Если это обычный статический переезд, делайте на nginx или Apache. PHP-редирект я считаю запасным инструментом, а не основным. Иначе вы загружаете приложение лишней работой, а ещё можете нарваться на проблемы с кэшированием и ранним выводом HTML.
Если у вас WordPress, посмотрите ещё как ускорить WordPress и настройку OPcache. Редиректы сами по себе не тормозят сайт катастрофически, но лишние уровни обработки очень быстро накапливаются.
Как избежать петель редиректов на практике
Я обычно начинаю с простого правила: один URL должен приводить к одной конечной версии за один шаг. Без промежуточных скачков. Если есть несколько правил, их нужно сводить в одну понятную логику. Это особенно важно при переходе на HTTPS, смене домена и нормализации слешей.
Например, плохая схема выглядит так:
- http://site.ru → https://site.ru
- https://site.ru → https://www.site.ru
- https://www.site.ru → https://site.ru
Это и есть петля. Человек может её даже не заметить, если браузер что-то закешировал, а вот бот или новый пользователь — легко. Нормально должно быть так:
- http://site.ru → https://site.ru
- http://www.site.ru → https://site.ru
- https://www.site.ru → https://site.ru
Всё в одну точку. И никаких “потом ещё раз перекинет”.
На деле петли часто возникают не на сервере, а в CMS. Например, WordPress сам канонизирует URL, а плагин редиректов добавляет свою логику. Или в Bitrix включён SEO-модуль, который исправляет адреса, а в nginx уже есть собственное правило. У меня был сайт на Битрикс 23.300 с каталогом на 15 тысяч страниц, где редирект петлял из-за слеша в конце URL категории. Одна сторона хотела /catalog, другая — /catalog/. Мелочь, а сайт падал в бесконечный переход.
Ещё один хороший приём — временно отключить всё лишнее и проверять конфигурацию по слоям:
- сервер;
- CDN;
- CMS;
- плагины;
- кэш.
Если редирект исчез после отключения плагина, проблема найдена. Если нет — ищете на уровне nginx, Apache или Cloudflare. И вот тут очень помогает статья про логи сайта, потому что без логов вы будете гадать неделями.
Как не создать 404 после редиректа
404 после редиректа обычно появляется тогда, когда старый URL перенаправили “на что-то похожее”, а не на реальную целевую страницу. Это распространённая ошибка после редизайна. Вроде бы URL похож, но на новой версии сайта такого раздела уже нет или он был переименован.
Я всегда делаю так: сначала выгружаю список старых URL, потом сопоставляю их с актуальной структурой. Если аналогов нет — ищу ближайший релевантный раздел, а не отправляю всё на главную. Редирект всех удалённых страниц на главную — это не решение. Это плохая идея и для SEO, и для пользователей.
Если у вас удалена карточка товара, лучше вести её на:
- актуальный аналогичный товар;
- категорию товара;
- раздел с похожими позициями;
- страницу снятого товара с рекомендациями, если она ещё жива.
А вот вести на главную — обычно ошибка. Поисковик видит несоответствие и часто воспринимает это как soft 404. Пользователь тоже злится, потому что ожидал одно, а его бросили в общий каталог без контекста.
Хорошая практика — перед включением редиректов прогонять список через скрипт и проверять доступность целевых URL. Например, я иногда использую простой SQL-экспорт или CSV, а потом проверяю HTTP-статусы списком. На больших проектах, где 500+ старых адресов, это уже не “на глаз”, а нормальная работа по карте перенаправлений. Если у вас проект серьёзный, посмотрите ещё SEO-аудит сайта и XML sitemap — там удобно сопоставлять структуру и искать потерянные URL.
Редиректы при переезде сайта или смене структуры
При миграции сайта редиректы надо планировать до запуска, а не после. Иначе вы получаете классическую ситуацию: новый сайт уже в проде, старые адреса умерли, а пользователи и поисковики видят 404. На моей практике это самая дорогая ошибка, потому что потом приходится быстро чинить SEO, поведенческие факторы и внутреннюю перелинковку одновременно.
Если вы переезжаете с WordPress на Bitrix или наоборот, схема должна быть такая:
- составить список старых URL;
- сопоставить их с новыми;
- настроить редиректы на сервере или в CMS;
- проверить цепочки и петли;
- обновить sitemap, внутренние ссылки и canonical;
- протестировать всё на staging-сайте.
Кстати, про staging я бы советовал не забывать вообще. Это лучший способ не ломать боевой сайт во время проверки. У меня есть отдельная статья про staging-сайт, и редиректы там как раз удобно тестировать без риска.
Если говорить о числах, то при большом переезде я обычно смотрю на такие метрики:
- не больше 1 редиректа на URL;
- 0 петель;
- 0 404 на ключевых посадочных;
- доля битых внутренних ссылок — стремится к нулю;
- время ответа на редирект — минимально, без лишних проверок в приложении.
И ещё одна вещь, о которой часто забывают: после смены структуры нужно обновить внутренние ссылки в контенте. Если в статьях и карточках товаров остались старые адреса, редирект будет срабатывать снова и снова. Это не смертельно, но лишняя нагрузка и лишняя задержка. Я обычно отдельно прогоняю замену по базе, а если проект на Laravel — по таблицам контента через SQL или Artisan-скрипты.
Что проверить после настройки редиректов
После любых правок я никогда не ограничиваюсь “главная открылась — значит всё ок”. Это самообман. Нужно проверить несколько уровней: ответ сервера, конечный URL, статус-код, canonical, sitemap и внутренние ссылки. Только тогда можно говорить, что редирект настроен нормально.
Минимальный чек после настройки:
- старый URL отдаёт 301 или 302, как задумано;
- Location ведёт сразу на конечную страницу;
- конечная страница отвечает 200 OK;
- нет цепочек из 2–3 переходов;
- нет петель;
- в Search Console не растёт число 404;
- в логах нет бесконечных повторов одного и того же запроса.
Я ещё смотрю, как редиректы ведут себя на мобильных устройствах и через CDN. Иногда на десктопе всё идеально, а мобильная версия или кэш CDN продолжает отдавать старый ответ. Это особенно заметно, если у вас подключён Cloudflare, Fastly или другой прокси-уровень. Тут полезно вспомнить и про скорость: лишние редиректы вполне могут просадить PageSpeed на 5–15 пунктов, особенно если их несколько подряд.
Если у вас уже есть проблемы с производительностью, посмотрите материалы по Core Web Vitals и по PageSpeed Insights. Редиректы редко бывают главной причиной провала, но в плохой конфигурации они легко добивают и без того слабый сайт.
Если нужно, я обычно подключаю и услугу поддержки: поддержка Bitrix, поддержка WordPress или общую доработку сайта. Потому что редиректы — это не разовая кнопка “включить”. Это часть технической поддержки сайта, и она должна жить вместе с логами, бэкапами и мониторингом.
И да, если сайт уже не раз переезжал или оброс костылями, сначала стоит проверить технический долг. Об этом у меня есть отдельная статья про технический долг сайта. Редиректы очень часто становятся его частью: вроде маленькое правило, а потом через год никто не понимает, почему страница открывается через три перескока.
Если говорить коротко, моя рабочая схема такая: 301 — для постоянных переездов, 302 — для временных сценариев, одно конечное направление, никаких цепочек, никаких дублей на разных уровнях. И если вы один раз нормально выстроите логику редиректов, потом сайт будет жить намного спокойнее. На деле это одна из тех вещей, которые лучше сделать один раз правильно, чем потом месяц разгребать 404 и падение индексации.
Нужна помощь с редиректами без ошибок?
Настроим 301 и 302 редиректы так, чтобы избежать петель, 404 и потери SEO-трафика.
