База знаний

JavaScript и Meta Refresh редиректы: когда можно, а когда нет

Когда перед вами стоит задача сделать редирект, есть соблазн не трогать сервер — написать пару строк JavaScript или добавить тег в HTML. Технически это работает. Практически — создаёт проблемы, о которых узнаёшь не сразу.

JavaScript и Meta Refresh редиректы — иллюстрация

Этот материал о том, как именно работают клиентские редиректы, почему они проигрывают серверным почти по всем параметрам — и в каких конкретных ситуациях они всё-таки уместны.


Как работают клиентские редиректы

Серверный редирект — это ответ на первый же HTTP-запрос. Браузер спрашивает: «Что по этому адресу?», сервер отвечает: «Переходи вот сюда» — и всё, одно сетевое взаимодействие.

Клиентский редирект работает иначе:

  1. Браузер делает запрос к серверу
  2. Сервер возвращает 200 OK и отдаёт HTML-документ
  3. Браузер парсит HTML (или скачивает и исполняет JavaScript)
  4. Только теперь происходит переход на новый адрес

Пользователь видит либо мигание пустой страницы, либо часть старого контента — в зависимости от того, насколько быстро срабатывает редирект. Поисковый робот видит то же самое: страницу с кодом 200, которая потом куда-то ведёт.


JavaScript: window.location

Самый распространённый способ JavaScript-редиректа — присвоение нового адреса объекту window.location:

// Самый частый вариант
window.location.href = 'https://new-domain.ru';

// Без добавления в историю браузера
window.location.replace('https://new-domain.ru');

// Эквивалентно href
window.location.assign('https://new-domain.ru');

Разница между href, replace() и assign() ощутима только для пользователя: replace() не добавляет запись в историю, поэтому кнопка «Назад» не вернёт на старую страницу. Для поисковых роботов все три варианта идентичны.

Редирект можно поставить и в теге <script> прямо в <head> — тогда он сработает до рендеринга страницы, что чуть лучше для UX, но не меняет сути с точки зрения индексации.


Meta Refresh

Второй клиентский метод — HTML-тег в блоке <head>:

<!-- Мгновенный переход -->
<meta http-equiv="refresh" content="0; url=https://new-domain.ru">

<!-- Переход через 5 секунд -->
<meta http-equiv="refresh" content="5; url=https://new-domain.ru">

Этому тегу около 30 лет — он появился ещё в Netscape Navigator и задумывался для автоматического обновления страниц новостей. Потом его начали использовать для редиректов, и с тех пор он несёт репутационный шлейф: именно meta refresh активно использовали спамеры и фишинговые сайты в 2000-е.

Существует и HTTP-версия — заголовок Refresh: в ответе сервера. Результат тот же, но если вы уже управляете ответом сервера — проще сразу поставить 301.

Ключевое различие с точки зрения Google: задержка в параметре content меняет интерпретацию. При content="0" редирект считается постоянным (как 301). При любой задержке > 0 — временным (как 302). Это официальная позиция Google Search Central.


Как видят Google и Яндекс

Google: два прохода

Google обрабатывает JavaScript в два этапа:

Первый проход — краулинг. Googlebot скачивает URL, получает HTML-ответ, парсит ссылки. Если в ответе JavaScript — страница попадает в очередь на рендеринг.

Второй проход — рендеринг. Web Rendering Service запускает headless Chromium, исполняет JS и обрабатывает результат. Между первым и вторым проходом может пройти от нескольких секунд до нескольких дней.

Это означает: при JS-редиректе Google сначала видит страницу-источник (с кодом 200 и её контентом), а адрес назначения узнаёт только после рендеринга. Всё это время в индексе может находиться не тот URL, что вы хотите.

Важная деталь: Google использует актуальную версию Chromium («evergreen Googlebot»), поэтому современные JS-конструкции он понимает. Проблема не в совместимости — проблема в очереди рендеринга и задержке.

Яндекс: JS-рендеринг в бета

Яндекс поддерживает JS-рендеринг через функцию «Рендеринг страниц JavaScript» в Вебмастере — но она находится в бета-статусе и работает не для всех сайтов и не для всех страниц. По умолчанию Яндекс сканирует HTML-ответ и не исполняет JavaScript.

Практический вывод: сайт на чистом клиентском рендеринге (React или Vue без SSR) в Яндексе будет индексироваться значительно хуже, чем в Google. JS-редирект для Яндекса — это лотерея.


Производительность

Клиентский редирект всегда медленнее серверного. Разница ощутимая.

Серверный 301:

→ DNS lookup
→ TCP connect
→ HTTP запрос
← 301 Location: new-domain.ru   ← всё, перенаправление здесь
→ DNS lookup (для нового домена)
→ TCP connect
→ HTTP запрос к новому URL

JS-редирект:

→ DNS lookup
→ TCP connect  
→ HTTP запрос
← 200 OK + HTML + ссылка на script.js
→ скачать script.js
→ выполнить JS
→ window.location = new URL         ← редирект только здесь
→ DNS lookup (для нового домена)
→ TCP connect
→ HTTP запрос к новому URL

Дополнительных шагов — три-четыре. При медленном соединении пользователь видит белый экран или мелькание старого контента. Core Web Vitals деградируют. Это не абстракция — это реальный пользовательский опыт, который Google учитывает в ранжировании.


Сравнительная таблица

МетодSEO-сигналНадёжностьСкоростьПередача веса
HTTP 301 / 308Постоянный ✓МаксимальнаяМгновенноДа
HTTP 302 / 307Временный ✓МаксимальнаяМгновенноНет
Meta Refresh (0 сек)ПостоянныйСредняя+1 RTTЧастично
Meta Refresh (>0 сек)ВременныйСредняяЗадержкаНет
JavaScript redirectПостоянный*Низкая+2–4 RTTНепредсказуемо

*Google может классифицировать как постоянный, но только после рендеринга.


Когда это всё-таки оправдано

Есть три ситуации, когда JS-редирект — это правильное решение, а не обходной манёвр:

1. После действия пользователя. Пользователь отправил форму, завершил оплату, вышел из системы. Сервер сделал своё дело, и теперь нужно перенаправить. Здесь window.location.replace() — абсолютно нормальный паттерн.

// После успешной оплаты
fetch('/api/checkout', { method: 'POST', body: data })
  .then(res => res.json())
  .then(data => {
    window.location.replace(`/success?order=${data.orderId}`);
  });

2. Страница с обратным отсчётом. «Вы будете перенаправлены через 5 секунд» — это UX-паттерн, а не SEO-решение. Пользователь должен видеть, что происходит.

let countdown = 5;
const timer = setInterval(() => {
  document.getElementById('counter').textContent = --countdown;
  if (countdown === 0) {
    clearInterval(timer);
    window.location.href = '/new-page';
  }
}, 1000);

3. Клиентская маршрутизация в SPA. React Router, Vue Router, Next.js — все они используют History API для навигации внутри приложения. Это не редирект в классическом смысле, а часть архитектуры. Здесь JS — единственный правильный инструмент.


Мифы и заблуждения

«Google умеет рендерить JS — значит, JS-редирект работает нормально»

Умеет. Но в очереди. Между краулингом и рендерингом проходит время. Для быстро меняющихся страниц или при переезде домена эта задержка критична.

«Meta Refresh с нулевой задержкой — это то же самое, что 301»

Не совсем. Google интерпретирует его как постоянный редирект, да. Но Яндекс — менее предсказуемо. И это всё равно дополнительный HTTP-запрос. Если доступен серверный редирект — используйте его.

«JS-редирект передаёт ссылочный вес, раз Google его видит»

Google передаёт ссылочный вес с JS-редиректов, но только после рендеринга страницы. Если страница находится в очереди рендеринга несколько дней — всё это время вес не передаётся. При быстром переезде важного домена это потери.

«Это решение временное, потом переделаем нормально»

Классика. Временное становится постоянным. Если нет доступа к серверу сейчас — используйте DNS-сервис переадресации: он настраивается за 5 минут и работает правильно с первого дня.

«DNS-редирект сложнее настраивать и поддерживать»

Ровно наоборот. Люди, которые так думают, представляют себе ручную правку зональных файлов на VPS в три часа ночи. Реальность с современными сервисами переадресации: вы указываете источник, назначение, тип — и больше ничего не делаете. Никогда. SSL-сертификат выпускается автоматически и продлевается сам. Нет сервера, за которым нужно следить. Нет файлов, которые нужно деплоить. Нет обновлений, которые нужно применять. Если нужно поменять адрес назначения — один клик в интерфейсе, изменение вступает в силу сразу. JS-редирект при том же сценарии требует: открыть редактор, поправить код, собрать проект, залить на хостинг, проверить. Это не «сложнее» и «проще» — это принципиально разные уровни операционной нагрузки.


Что использовать вместо

Для большинства задач — серверный редирект. Если доступа к серверу нет, варианты в порядке убывания надёжности:

  1. DNS-сервис переадресации — принимает домен на свои серверы, автоматически выдаёт SSL и настраивает правильный 301. Хостинг не нужен вообще: никаких файлов, никакого сервера, никакого кода. Редирект настраивается через интерфейс и работает на уровне DNS — домен просто указывает на сервис, который всё делает сам.

  2. Серверный скрипт — если контролируете хостинг, но не конфиг сервера: PHP header('Location: ...') или аналог на вашем бэкенде. Правильный HTTP-статус, никакого JS. Но для этого нужен работающий хостинг с файлами на нём.

  3. Meta Refresh (0 сек) — только если два предыдущих варианта недоступны и нужен быстрый временный фикс. Тоже требует загрузки HTML-файла куда-то.

  4. JavaScript — только для трёх случаев, описанных выше.

Обратите внимание на контраст: JS-редирект и meta refresh требуют, чтобы где-то лежал файл — а значит, нужен хостинг, деплой, поддержка. DNS-сервис переадресации работает без всего этого. Если задача — просто перенаправить домен, нет смысла поднимать инфраструктуру ради одной строки кода.

Если ситуация не подходит ни под один из трёх оправданных случаев — это не аргумент в пользу JS-редиректа. Это аргумент в пользу того, чтобы получить нормальный доступ.

Часто задаваемые вопросы

Передаёт ли JavaScript редирект ссылочный вес?
Не гарантированно. Google может интерпретировать JS-редирект как постоянный, но только после рендеринга — это происходит с задержкой от секунд до нескольких дней. Яндекс рендерит JS непредсказуемо. Ни один клиентский редирект не заменяет серверный 301 при переезде домена или страницы.
Чем отличается window.location.href от window.location.replace?
Для SEO — ничем. Для пользователя — replace() не добавляет запись в историю браузера, поэтому кнопка «Назад» не работает. href и assign() историю сохраняют. Поисковые роботы оба варианта обрабатывают одинаково — через очередь рендеринга.
Можно ли использовать meta refresh вместо 301?
Только как временное решение, если у вас нет доступа к серверу. Google интерпретирует мгновенный meta refresh (content="0") как постоянный редирект, Яндекс — менее предсказуемо. Задержка загрузки, UX-проблемы и возможный фишинговый флаг делают его нежелательным в продакшене.
Почему Google 'умеет' рендерить JS, но JS-редирект всё равно плохой?
Google рендерит JS в два прохода: сначала сканирует HTML-ответ, потом ставит страницу в очередь рендеринга. Между краулингом и рендерингом может пройти от нескольких секунд до нескольких дней. Всё это время редирект не работает с точки зрения индексации. Серверный редирект срабатывает в первом же ответе, без второго прохода.
Когда JS редирект всё-таки оправдан?
В трёх случаях: (1) редирект после действия пользователя (логин, отправка формы), (2) таймер с обратным отсчётом на странице-заглушке, (3) SPA с клиентской маршрутизацией — там это часть архитектуры. Во всех остальных случаях используйте серверный редирект.
Яндекс рендерит JavaScript?
Частично и нестабильно. В Яндекс Вебмастере есть бета-функция 'Рендеринг страниц JavaScript', но массово Яндекс не рендерит JS так же, как Google. Сайты на чистом клиентском рендеринге (React/Vue без SSR) индексируются значительно хуже в Яндексе, чем в Google.
Meta refresh — это HTML или HTTP?
Может быть и тем, и другим. В HTML это тег <meta http-equiv='refresh'> в <head>. В HTTP — это заголовок Refresh: в ответе сервера. Оба работают, оба несут те же ограничения.

Связанные материалы

Серверный редирект за 5 минут

redirekto.ru настраивает правильный 301 на уровне DNS — без доступа к серверу, с автоматическим HTTPS и без всякого JavaScript.

Попробовать бесплатно
A B

платформа редиректов

редиректо.ru

Включайте предсказуемую маршрутизацию доменов: DNS, HTTPS и контроль правил в одной панели.