Ссылка приводит не туда, и вам нужно понять, что произошло между кликом и итоговой страницей. Стандартный первый ход — curl, и он правильный: тест на 60 секунд про gclid на этом сайте построен как раз на curl -sIL, и про серверные редиректы он говорит правду. А потом цепочка в терминале выглядит чистой, а браузер всё равно оказывается в другом месте, и инструмент незаметно упёрся в свой предел.

Причина в том, что в HTTP-ответах живёт только часть редиректов. Остальные происходят внутри страницы или внутри самого браузера, и сколько ни добавляй -L, они не появятся. Эта статья про то, как цепочку увидеть, а не построить: способам её создать на Cloudflare посвящено отдельное сравнение.

Три редиректа, которых curl вам не покажет

JavaScript-редирект — это 200. Сервер отвечает обычной страницей, страница выполняет location.replace() или присваивает location.href, и браузер уходит. curl печатает HTTP/2 200, не сообщает ни о каком редиректе и выходит. Каждая промежуточная страница-прослойка, каждый трекинговый хоп на скрипте, каждая страница «проверяем ваш браузер» — из этого класса.

Meta refresh — тоже 200. <meta http-equiv="refresh" content="0;url=..."> лежит в теле HTML, а curl HTML не разбирает. Та же чистая строка статуса и тот же молчаливый переход в браузере.

HSTS-апгрейд вообще не покидает браузер. После одного визита на сайт, отдающий Strict-Transport-Security, браузер переписывает http:// в https:// до того, как запрос вообще будет отправлен. DevTools показывает это как 307 Internal Redirect — ответ, которого сервер никогда не присылал. curl по умолчанию состояние HSTS не хранит, поэтому каждый раз заново идёт на http://-адрес и показывает вам серверный 301 — хоп, который ваши возвращающиеся посетители давно перестали проходить.

301, серверный хоп
curl его видит

HSTS 307, внутренний
повторные визиты, только браузер

302, серверный хоп
curl его видит

200 + location.href
только браузер, curl тут останавливается

http://go.example/deal

https://go.example/deal

https://shop.example/landing

https://shop.example/en/deal

Одна цепочка, две версии: все её хопы и место, где curl перестаёт читать

Поверх механики есть ещё сессия. curl ходит без кук, поэтому цепочка, которая ветвится по состоянию входа, куке согласия или принадлежности к A/B-группе, уводит curl не туда, куда ушёл человек, сообщивший о проблеме. Цепочка, которую проверили вы, — не та цепочка, по которой прошёл он, даже когда обе настоящие.

DevTools её покажет, если держать правильно

Браузер, разумеется, знает цепочку целиком, и панель Network её покажет — с церемониями. Preserve log должен быть включён, иначе панель очищается на каждом переходе, и нужный хоп стирает собственные улики. Фильтр Doc убирает шум из сотни подзапросов, которые делает современная страница. Серверные хопы после этого видны отдельными строками со своими статусами 301 и 302.

Клиентские хопы там тоже есть, но без подписи. JavaScript-редирект — это просто ещё один запрос документа; в строке ничто не говорит «это был редирект», а связать его со страницей, которая его запустила, значит читать колонку Initiator. Meta refresh выглядит так же. Сделать это один раз — пять минут археологии. Делать так на каждое обращение — и начинает хотеться, чтобы браузер вёл запись сам.

Регистратор вместо засады

Именно это и делает Redirect Inspector. Это наше собственное расширение с открытым кодом (Apache 2.0, код на GitHub), и версия 2.3 вышла самым большим обновлением за всё время — она и стала поводом для этой статьи. Расширение слушает конвейер запросов самого браузера и записывает каждую цепочку, пока вы ходите по сайтам: серверные хопы с их кодами статуса, клиентские переходы (скрипт или meta refresh) с бейджем JS и внутренние апгрейды браузера с пометкой HSTS. Цепочки сгруппированы по сессиям браузера, трекинговые пиксели и рекламные маяки отфильтрованы по умолчанию. На каждой карточке — общее время цепочки, а на панели анализа — время каждого хопа.

Что добавила версия 2.3, коротко:

  • Проверить адрес, не заходя на него. Вставьте адрес в док внизу панели; он откроется в невидимой фоновой вкладке, цепочка снимется через обычный конвейер, а вкладка закроется сама. Подозрительную ссылку из обращения можно проследить, и она ни разу не займёт ваш экран.
  • Экспорт, который влезает в баг-репорт. Скопировать чистую сводку, скачать сырую цепочку в JSON или скопировать готовую команду curl, воспроизводящую серверную часть цепочки, — и круг замыкается на терминале, где расследование началось.
  • Боковая панель вместо попапа в Chrome и Edge, чтобы список цепочек оставался открытым, пока вы ходите по сайтам. В Firefox остаётся попап.
  • Локальный анализ. Девять проверок на цепочку: петли, прыжки туда-обратно, длина цепочки, смешанные типы редиректов, отскоки авторизации, хопы согласия, трекинговый шум, определение CDN, чем цепочка кончилась.
  • Поиск по всем записанным адресам, очистка с возможностью отменить, горячие клавиши и полный перевод интерфейса на семь языков.

То, что важно для инструмента, наблюдающего за вашим трафиком: всё работает локально. Ни аккаунтов, ни аналитики, ни телеметрии, и по умолчанию вообще никаких сетевых запросов; снятые цепочки лежат в хранилище браузера и машину не покидают. Расширение есть в Chrome Web Store, Firefox Add-ons и Edge Add-ons.

Какой инструмент что видит

Что нужно curl -sIL DevTools Network Redirect Inspector
Серверные хопы (301, 302, 307, 308) да при включённом Preserve log да, пишутся по ходу навигации
HSTS-апгрейд нет, каждый раз видит серверный 301 показан как 307 Internal Redirect помечен HSTS
JS и meta refresh нет, оба — это 200 неподписанный запрос документа пойманы, помечены как клиентский редирект
Цепочка, которую получает ваша сессия (куки, вход) нет да да
Тайминг один общий через -w по запросам, размазан по строкам общий на цепочку, дельта на хоп
Запись, которую потом можно искать и выгружать нет стирается при закрытии панели сессии, поиск, экспорт в JSON и curl

Онлайновые чекеры редиректов в таблицу не попали намеренно: они запрашивают адрес из своего дата-центра, поэтому цепочка, которая ветвится по стране, языку или кукам, покажет вам версию для дата-центра. Это та же слепая зона, что у curl, плюс чужой IP.

Где расширение останавливается

Расширение записывает то, что прислали вашему браузеру. Цепочка, которая ветвится по географии, всё равно покажет вам ветку для вашей страны и ничью больше, а что на том же адресе видит Googlebot — вопрос совсем другой. Проверка адреса — это настоящий переход в неактивной вкладке, так что ваши куки применяются, а визит попадает в историю: это удобство, а не изолированная песочница. И смотреть цепочки расширение может только по одному браузеру за раз, на той машине, где оно установлено.

Для отладки ссылки, которая перед вами, это вся работа целиком, и расширение бесплатное. Останавливается оно там, где вопрос меняется с «что случилось с этим кликом» на «какие из моих доменов редиректят неправильно прямо сейчас». Чтобы ответить на второй, надо по расписанию слать одну и ту же пробу на каждый домен и сравнивать со вчерашним, а этого не умеет ни один браузерный инструмент. Скрипт аудита — ручная версия такого ответа, а 301.st — версия, которая работает непрерывно, по всему портфелю, и присылает оповещение, когда цепочка меняется. Для открытой у вас вкладки поставьте расширение и читайте цепочку.