User-Agent
User-Agent
User-Agent — это заголовок HTTP-запроса, в котором клиент (браузер, приложение, робот, скрипт) сам сообщает серверу, кто он такой: название программы, версию, движок, иногда операционную систему и устройство. Это самопредставление, а не удостоверение личности: сервер получает ровно то, что клиент решил написать.
История
Слово «user agent» (агент пользователя) старше веба. В инженерных стандартах так называют программу, которая действует от имени человека: почтовый клиент — это mail user agent (MUA), браузер — web user agent. Идея простая: между человеком и сетью стоит посредник, и у посредника есть имя.
1990–1996: рождение заголовка. Первая версия HTTP (её потом назвали HTTP/0.9), которую Тим Бернерс-Ли запустил в CERN в 1990–1991 годах, вообще не имела заголовков — запрос состоял из одной строки GET /page. Заголовки появились по мере того, как протокол обрастал возможностями, и в мае 1996 года вышел RFC 1945 (HTTP/1.0, авторы — Тим Бернерс-Ли, Рой Филдинг, Хенрик Фристик Нильсен). В нём заголовок User-Agent описан официально: «для статистических целей, отслеживания нарушений протокола и автоматического распознавания клиентов, чтобы подстраивать ответ». Заметь: уже тогда в стандарт заложили оба применения — и аналитику, и подстройку контента.
1993–1995: браузерные войны и «Mozilla». Самый смешной и поучительный кусок истории. Браузер NCSA Mosaic (1993) представлялся как NCSA_Mosaic/2.0 (Windows 3.1). Затем появился Netscape Navigator, внутреннее кодовое имя которого было Mozilla («Mosaic killer», убийца Мозаика). Он писал Mozilla/1.0 (Win3.1) и поддерживал фреймы, а Mosaic — нет. Сайты начали проверять: «если в UA есть Mozilla — отдаём версию с фреймами». Когда в 1995 году вышел Internet Explorer от Microsoft и тоже умел фреймы, он получал урезанную версию страниц. Решение Microsoft: притвориться. IE стал писать Mozilla/2.0 (compatible; MSIE 3.0; Windows 95). С этого момента заголовок перестал быть честным.
2000-е: матрёшка. Дальше каждый новый браузер наслаивал чужие имена, чтобы его не обделили. Konqueror с движком KHTML писал like Gecko (Gecko — движок Firefox). Apple в 2003 году взяла KHTML, сделала из него WebKit и Safari — и Safari писал AppleWebKit/... (KHTML, like Gecko) Safari/.... Google Chrome (2008) построен на WebKit и добавил себя сверху. Поэтому сегодняшний Chrome на Android выглядит примерно так:
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/129.0.0.0 Mobile Safari/537.36
В одной строке упомянуты пять разных браузеров, и только один из них — правда. Эту историю хорошо рассказал Аарон Андерсен в заметке «History of the browser user-agent string» (2008) — её до сих пор цитируют.
2020–2023: заморозка. Длинный и подробный UA оказался подарком для fingerprinting (отпечатка браузера — идентификации человека без cookie по совокупности признаков). В 2020 году Google объявил программу User-Agent Reduction: в Chrome примерно с версий 101–113 (2022–2023) из строки постепенно убрали точную версию ОС, модель устройства и минорную версию браузера. Отсюда буква K вместо модели телефона и вечный Android 10 в примере выше. Взамен — механизм User-Agent Client Hints (о нём ниже). Safari и Firefox тоже заморозили часть полей. Актуальный стандарт HTTP-семантики — RFC 9110 (2022), раздел 10.1.5, — описывает User-Agent и прямо предупреждает о рисках для приватности.
Что это такое
Технически User-Agent — одна строка текста в заголовках запроса. Её отправляет клиент при каждом обращении к серверу: за HTML-страницей, картинкой, скриптом, API-ответом. Формат рекомендован стандартом: последовательность «продуктов» вида имя/версия, между ними — комментарии в скобках. Например, curl/8.7.1, python-requests/2.32.3, YandexBot/3.0.
Ключевое свойство: строку формирует клиент, и сервер никак не может её проверить. Браузер пишет её честно (со всеми историческими масками), библиотеки пишут своё имя по умолчанию, а любой скрипт может подставить что угодно одной строкой кода. Поэтому User-Agent — это заявление, а не факт.
Кто и зачем читает UA:
- Сервер — чтобы решить, какую версию отдать: мобильную или десктопную, с редиректом в приложение или без, со старыми полифиллами (заплатками для старых браузеров) или без.
- Аналитика — Яндекс Метрика, Google Analytics и логи веб-сервера раскладывают трафик по браузерам, ОС, типам устройств.
- Антибот и антифрод — как один из многих сигналов: пустой UA, UA от
python-requestsили несовпадение UA с другими признаками — повод присмотреться. - Роботы поисковиков и рекламных систем — представляются своими UA, и сайты по ним решают, как с ними обращаться.
Похожие вещи, с которыми его путают:
- User-Agent vs IP-адрес. IP говорит, откуда пришёл запрос, UA — кем клиент себя называет. IP подделать сложнее (нужен прокси или чужой сервер), UA — тривиально. Поэтому серьёзные проверки опираются на IP, а UA — лишь подсказка.
- User-Agent vs fingerprint. Отпечаток браузера — это десятки признаков (шрифты, размер экрана, рендер canvas, часовой пояс). UA — лишь один из них, самый дешёвый в подделке.
- User-Agent vs Client Hints. Client Hints — это набор отдельных заголовков (
Sec-CH-UA,Sec-CH-UA-Mobile,Sec-CH-UA-Platform), где браузер по умолчанию сообщает минимум, а подробности (модель, точная версия) — только если сервер явно попросил. То есть «расскажи о себе» превращается в «спрашивай — отвечу». - User-Agent vs
navigator.userAgent. Первое — заголовок, который видит сервер. Второе — та же строка, доступная JavaScript на странице. Обычно совпадают, но расширения и режимы эмуляции могут их рассинхронизировать — и это само по себе признак для антибота.
Аналогии из жизни
Бейдж на конференции. Каждый участник сам вписывает имя и компанию в бейдж, и организаторы по бейджу решают, пускать ли в VIP-зону. Работает: люди в основном пишут правду, и по бейджам удобно считать, кто пришёл. Где ломается: на конференции есть регистрация с паспортом до выдачи бейджа, а в HTTP никакой регистрации нет — бейдж пишут на входе маркером, и никто не сверяет. Плюс в вебе все участники исторически пишут на бейдже «Mozilla», чтобы их пустили: представь конференцию, где у каждого второго на бейдже стоит имя самого популярного спикера.
Акцент по телефону. Звонишь в службу поддержки, оператор по речи понимает, что ты из другого региона, и переключает на подходящую линию. Работает: сервер действительно по «манере представления» подстраивает ответ. Где ломается: акцент сложно подделать, а UA — одна строка. И акцент не меняется от звонка к звонку, а UA меняется с каждым обновлением браузера — логика вида «если версия ровно такая-то» устаревает за месяцы.
Этикетка на банке. На складе ящики сортируют по надписи на этикетке, не вскрывая. Быстро и почти всегда верно. Где ломается: если кто-то переклеит этикетку, склад отправит ящик не туда — ровно так боты с «браузерным» UA проходят через фильтры, настроенные только на UA. Честная сортировка требует хотя бы выборочно вскрывать ящики — в вебе это проверка IP, поведения, выполнения JavaScript.
Как это работает
Разберём путь одного запроса.
Шаг 1. Клиент собирает строку. Браузер формирует UA из зашитого шаблона: платформа, движок, версия. Библиотеки делают проще: curl шлёт curl/<версия>, Python-библиотека requests — python-requests/<версия>, а голый urllib — Python-urllib/3.x. Программист может переопределить заголовок одной строкой.
Шаг 2. Запрос уходит на сервер.
GET /go?campaign=42 HTTP/1.1
Host: example.ru
User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36
Accept: text/html
В HTTP/2 и HTTP/3 заголовок передаётся в сжатом бинарном виде, но смысл тот же.
Шаг 3. Сервер разбирает строку. Обычно — поиском подстрок или регулярными выражениями (шаблонами текста): «есть Android и есть Chrome/ — значит Chrome на Android», «есть iPhone — iOS». Для серьёзного разбора есть готовые парсеры: открытые (ua-parser с портами на разные языки, ua-parser-js) и коммерческие базы устройств (DeviceAtlas, 51Degrees, WURFL). Порядок проверок критичен: Chrome на iOS содержит CriOS, Firefox на iOS — FxiOS, а оба при этом содержат Safari и работают на WebKit.
Шаг 4. Сервер принимает решение. Типичные ветки:
если UA похож на робота (YandexBot, Googlebot) -> отдать обычную HTML-страницу
иначе если мобильный Android-браузер -> отдать ссылку на приложение (intent://)
иначе если iOS -> отдать универсальную ссылку
иначе -> обычная веб-страница
Шаг 5. Ответ помечается заголовком Vary: User-Agent. Это подсказка кэшам и CDN (сетям доставки контента): «ответ зависит от UA, не отдавай десктопную версию мобильному». Без этого кэш может перемешать варианты. Минус — кэш дробится на тысячи вариантов, поэтому CDN часто нормализуют UA до пары «мобильный/десктоп».
Шаг 6. Строка попадает в лог. Стандартный формат логов nginx и Apache (combined) пишет UA в конце строки. Именно по логам потом отвечают на вопросы «сколько ботов», «какие браузеры» и «приходил ли вообще такой клиент».
Client Hints — как это выглядит. Браузер на Chromium по умолчанию шлёт:
Sec-CH-UA: "Chromium";v="129", "Not=A?Brand";v="8"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Platform: "Android"
Строка Not=A?Brand — нарочно абсурдная (GREASE — «смазка» протокола): её добавляют, чтобы сайты не писали хрупких проверок «ровно этот список брендов». Если серверу нужна модель устройства, он отвечает заголовком Accept-CH: Sec-CH-UA-Model, и следующие запросы её уже содержат. Firefox и Safari на момент написания Client Hints в таком виде не поддерживают — точно проверь на caniuse.com по запросу «User-Agent Client Hints».
UA — не доказательство
Любое решение, которое даёт доступ, деньги или доверие, не может опираться только на User-Agent. Бот пишет Chrome за одну строку кода, а настоящий робот поисковика проверяется по IP: обратный DNS-запрос должен вернуть домен поисковика, а прямой — тот же IP.
Как проверить робота всерьёз. И Google, и Яндекс официально описывают одну и ту же процедуру: взять IP запроса, сделать обратный DNS-запрос (PTR), убедиться, что имя оканчивается на домен поисковика (googlebot.com, google.com, yandex.ru, yandex.net, yandex.com), затем сделать прямой запрос по этому имени и убедиться, что вернулся тот же IP. Google дополнительно публикует списки IP-диапазонов своих роботов в JSON.
Где встречается в обычной жизни
- «Скачайте наше приложение». Открываешь ссылку маркетплейса с телефона — видишь баннер с кнопкой в App Store или Google Play, с компьютера — нет. Сервер или скрипт на странице прочитал UA и понял, какой у тебя телефон.
- «Ваш браузер устарел». Банк или госсервис показывает плашку с просьбой обновиться — это проверка версии браузера из UA (иногда — ложная тревога, если твой браузер незнаком сайту).
- Письмо «вход с нового устройства». Почта или соцсеть пишет: «Вход с Chrome на Windows, Москва». «Chrome на Windows» — это разобранный UA, «Москва» — геолокация по IP.
- Список активных сессий. В Telegram или Google-аккаунте есть экран «устройства» с названиями вроде «Safari, macOS» — тоже из UA и Client Hints.
- Версия «для компьютера» в мобильном браузере. Кнопка «Полная версия сайта» в Chrome или Safari буквально подменяет UA на десктопный — и сайт перестаёт отдавать мобильную вёрстку.
Где встречается в IT и бизнесе
- Диплинки и редиректы в приложение. Нужно, когда рекламная ссылка должна открывать мобильное приложение на Android (
intent://), универсальную ссылку на iOS и обычный сайт на компьютере. Ветка выбирается по UA — и ошибка в условии может отправить в приложение того, кому нужна веб-страница, например робота модерации. - Антибот и чистка заявок. Нужно, когда формы или квизы засыпают спамом. UA — дешёвый первый фильтр: пустой, библиотечный (
python-requests,HeadlessChrome) или странно устаревший. Но серьёзные боты шлют идеальный UA, поэтому он работает только в связке с IP, cookie аналитики, временем заполнения и поведением. - SEO и работа с роботами. Нужно, когда сайт должен гарантированно показывать роботам ту же страницу, что и людям. Отдавать роботу другой контент — клоакинг, за который поисковики понижают или банят. Проверка «что увидит робот» — это запрос с UA робота, например
curl -A "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)". - Аналитика и продуктовые решения. Нужно, когда решаешь, поддерживать ли старые браузеры: доля в логах по UA говорит, сколько пользователей потеряешь.
- Интеграции и API. Нужно, когда пишешь скрипт к чужому API: хорошим тоном считается честный UA вида
moysait-sync/1.2 (+https://moysait.ru/contact). Многие API (например, Wikipedia) прямо требуют осмысленный UA и могут блокировать безымянные запросы.
Отсутствие — тоже данные
Самые полезные выводы по UA часто негативные: «за две недели с IP поисковика не было ни одного запроса с мобильным Android-UA» опровергает гипотезу надёжнее, чем любые рассуждения о том, как робот должен себя вести.
Кто пользуется
- Все браузеры — Chrome (по разным оценкам, около 65% мирового рынка браузеров, по данным StatCounter), Safari, Edge, Firefox, Яндекс Браузер. Каждый из них шлёт UA в каждом запросе, то есть речь о триллионах запросов в сутки.
- Поисковые и рекламные роботы. Googlebot, YandexBot, YandexMobileBot, Bingbot, а также отдельные роботы модерации и проверки посадочных страниц рекламных систем. Их списки UA публикуются в справке поисковиков.
- CDN и WAF (межсетевые экраны веб-приложений). Cloudflare, Akamai, Fastly используют UA в правилах и в классификации ботов — но в связке с десятками других сигналов, включая TLS-отпечаток клиента (JA3/JA4).
- Счётчики аналитики. Яндекс Метрика и Google Analytics разбирают UA для отчётов «Технологии»/«Устройства»; Метрика в том числе фильтрует роботов.
- Сервисы разбора устройств. DeviceAtlas, 51Degrees, WURFL — коммерческие базы, которые по UA и Client Hints определяют конкретную модель телефона. Ими пользуются рекламные платформы и операторы связи.
Альтернативы и конкуренты
User-Agent Client Hints.
Плюсы: структурированные поля, меньше утечка данных по умолчанию, не нужно парсить исторический мусор.
Минусы: поддерживаются в основном браузерами на Chromium; подробности приходят только со второго запроса после Accept-CH.
Feature detection (проверка возможностей) на клиенте.
Плюсы: проверяешь не «какой браузер», а «умеет ли он нужное» ('serviceWorker' in navigator) — надёжно и не устаревает.
Минусы: работает только в JavaScript на странице, сервер на первом запросе этого не знает.
CSS media queries и адаптивная вёрстка.
Плюсы: одна страница сама подстраивается под экран, не нужно угадывать устройство.
Минусы: не решает задач уровня сервера — редирект в приложение или выдачу разных данных.
Проверка по IP и обратному DNS / fingerprinting.
Плюсы: гораздо сложнее подделать, годится для верификации роботов и антибота.
Минусы: дороже в реализации, fingerprinting упирается в приватность и законодательство о персональных данных.
Когда НЕ стоит использовать
- Для безопасности и доступа. Не открывай админку, не снимай капчу и не давай лимиты «потому что UA похож на Googlebot» — потому что подделка стоит одну строку, и это первый приём любого бота.
- Для тонкого ветвления вёрстки. Не отдавай разный HTML «под Safari 17» и «под Chrome 129» — потому что UA заморожены, врут исторически, и через пару обновлений ветка сломается. Используй feature detection и адаптивный CSS.
- Как единственный признак в аналитических выводах. Не делай вывод «это были роботы» или «это были живые люди» только по UA — потому что и боты маскируются под людей, и живые пользователи иногда приходят со странных клиентов (встроенные браузеры приложений, старые телевизоры).
Связанные понятия
- HTTP-заголовки — метаданные запроса и ответа:
Accept,Referer,Cookie,Vary; UA — лишь один из них. - Client Hints — механизм, где сервер запрашивает у браузера нужные подробности отдельными заголовками.
- Browser fingerprinting — идентификация браузера по совокупности признаков без cookie.
- Обратный DNS (PTR-запись) — получение имени по IP; основа проверки «настоящих» роботов.
- Deep link /
intent://— ссылка, открывающая конкретный экран мобильного приложения; часто выбирается по UA. - Клоакинг — показ роботам поисковика иного контента, чем людям; нарушение правил поисковиков.
Литература и источники
- RFC 9110 «HTTP Semantics» (2022), раздел 10.1.5 User-Agent — https://www.rfc-editor.org/rfc/rfc9110 (en).
- MDN Web Docs: «User-Agent» и «Browser detection using the user agent» — https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent (en, есть частичный ru-перевод).
- Aaron Andersen, «History of the browser user-agent string» (2008) — искать в Google по названию (en).
- Спецификация User-Agent Client Hints от WICG — искать «wicg ua-client-hints» (en); обзор на web.dev по запросу «user-agent reduction».
- Справка Яндекс Вебмастера «Как проверить, что робот принадлежит Яндексу» и Google Search Central «Verifying Googlebot» — искать по этим названиям (ru/en).
- Wikipedia: «User agent» — https://en.wikipedia.org/wiki/User_agent (en).
Где встретилось у меня
В одном моём проекте рекламный подрядчик предположил, что модерация рекламной системы не может открыть посадочную, потому что редирект отдаёт мобильным ссылку на приложение. Разбор кода и логов показал: такая ссылка выдаётся только при Android-UA с Chrome, а с IP поисковика за две недели таких запросов не было — гипотеза снялась. В тот же день UA всплыл и в задаче по защите квизов от спама как один из сигналов антибота.
Попробуй сам
Выполни curl -sI -A "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" https://example.ru/ и сравни ответ с обычным запросом из браузера. Если твой сайт отвечает по-разному — стоит понять, почему.
Краткое резюме
- User-Agent — строка, в которой клиент сам себя называет; сервер не может её проверить.
- Из-за браузерных войн 1990-х почти каждый браузер пишет «Mozilla» и перечисляет чужие движки; с 2022 года Chrome ещё и заморозил подробности, передав их в Client Hints.
- UA хорош для аналитики, выбора ветки редиректа и первичного фильтра ботов, но не годится как доказательство.
- Настоящего робота поисковика проверяют по IP через обратный и прямой DNS, а не по UA.
- Самые сильные выводы по UA — из логов: что реально приходило, а чего не было ни разу.