Определение браузера с помощью user agent
Определение браузера с помощью строки user agent (анализ UA)
Вместе с каждым запросом к серверу браузеры отправляют HTTP-заголовок User-Agent HTTP со значением, называемым строкой user agent (UA). Эта строка предназначена для идентификации браузера, его версии и хостовой операционной системы.
User-Agent: <product> / <product-version> <comment>
Эту строку также можно получить через свойство navigator.userAgent в JavaScript:
console.log(window.navigator.userAgent); // Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0
Может возникнуть соблазн разобрать строку UA (этот процесс иногда называют «анализом UA») и изменить поведение сайта в зависимости от её значений, но надёжно сделать это очень сложно, и такой подход часто становится причиной ошибок.
В этом документе описаны распространённые подводные камни использования строки UA для определения браузера и рекомендуемые альтернативы. В конце мы приводим несколько советов по определению UA на основе строки, но делать это следует только в случае крайней необходимости!
Почему определение возможностей лучше определения браузера
Чтобы показать, почему попытки адаптировать функциональность сайта для разных браузеров усложняют разработку и могут привести к ошибкам, рассмотрим следующий пример. Приложение хочет использовать функцию splitUpString() в JavaScript с помощью проверки с просмотром назад (?<=…):
let splitUpString;
if (navigator.userAgent.includes("Chrome")) {
const camelCaseExpression = new RegExp("(?<=[A-Z])");
splitUpString = (str) => String(str).split(camelCaseExpression);
} else {
// This fallback is inefficient, but it works
splitUpString = (str) =>
String(str)
.split(/(.*?[A-Z])/)
.filter(Boolean);
}
console.log(splitUpString("fooBar")); // ["fooB", "ar"]
console.log(splitUpString("jQWhy")); // ["jQ", "W", "hy"]
В этом коде сделано несколько предположений, которые могут оказаться неверными и привести к сбою, если запустить его в неподходящем браузере или неподходящей версии браузера:
-
Все строки user agent, содержащие подстроку
Chrome, указывают на браузер Chrome.Одна из главных проблем определения браузера на основе строк UA заключается в том, что браузеры и user agent регулярно выдают себя за другие браузеры или включают сведения сразу о нескольких браузерах.
-
Функция просмотра назад всегда доступна в Chrome. В действительности браузер может оказаться более старой версией Chrome, в которой эта функция ещё не поддерживалась, или более поздней версией Chrome, из которой её удалили.
-
Самое важное: предполагается, что ни один другой браузер не поддерживает эту функцию, хотя её могут добавить в любой другой браузер в любое время. Все браузеры, не соответствующие условию, будут вынуждены использовать неэффективный запасной вариант.
Важно отметить, что эти проблемы возникают независимо от способа определения браузера: при анализе UA, использовании подсказок клиента, наличии, отсутствии или содержимом других HTTP-заголовков и так далее. Знание того, какой браузер используется, не имеет значения: в этом случае нам нужно определить наличие возможности, что подробнее описано ниже.
Альтернативы анализу UA
В следующих разделах описаны альтернативы определению браузера, которые надёжнее и применимы в гораздо большем числе ситуаций, чем анализ UA.
Определение возможностей
При определении возможностей вы проверяете, доступна ли клиенту конкретная функция, вместо того чтобы выяснять, какой браузер отображает страницу. Если функция не поддерживается, используется запасной вариант. В следующем примере проверяется, поддерживает ли клиент Geolocation API. Для этого можно проверить наличие свойства geolocation в глобальном объекте Navigator.
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
// show the location on a map, such as the Google Maps API
});
} else {
// Show a static map instead
}
Так можно проверять множество возможностей. Например, можно определить, можно ли просматривать PDF-файлы непосредственно в браузере или поддерживается ли VirtualKeyboard API, и так далее:
if ("application/pdf" in navigator.mimeTypes) {
// browser supports inline viewing of PDF files.
}
if ("virtualKeyboard" in navigator) {
// browser supports the Virtual Keyboard API
}
Для стилей возможности также можно проверять в CSS с помощью директивы @supports, сочетая её с ключевым словом not, если нужно проверить отсутствие возможности. Подробнее об использовании этого подхода в CSS см. в статье Использование запросов возможностей.
@supports (display: grid) {
.box {
display: grid;
gap: 2rem;
}
}
@supports not (property: value) {
/* CSS rules for fallback */
}
В редких случаях, когда поведение одной и той же функции различается в разных браузерах, следует проверить реализацию API в браузерах и на этом основании определить, как его использовать. Подробнее см. в документации Реализация определения возможностей.
Определение мобильных устройств
Распространённый неправильный способ применения анализа UA (и подсказок клиента) — определять, является ли клиент мобильным устройством. Обычно на самом деле требуется выяснить, удобно ли пользоваться устройством пользователя с помощью сенсорного ввода и имеет ли оно небольшой экран, чтобы, например, оптимизировать сайт, добавив кнопкам дополнительные отступы.
Вместо этого следует определять возможности с помощью современных API. Например, чтобы проверить поддержку сенсорного ввода, проверьте свойство maxTouchPoints интерфейса Navigator:
if (navigator.maxTouchPoints > 1) {
// browser supports multi-touch
}
Для других задач, например создания макета, используйте современные средства CSS, такие как flexbox и grid, чтобы создавать гибкие макеты. Вместо того чтобы скрывать содержимое на небольших экранах, динамически изменяйте макет. Для большинства изменений макета достаточно медиазапросов, что уменьшает необходимость вносить изменения с помощью JavaScript.
Чтобы обеспечить плавные переходы при повороте устройства или переключении между режимами экрана, ознакомьтесь с материалом Определение ориентации устройства. Для складных устройств доступны более новые API, например Device Posture API, однако обязательно проверьте данные о совместимости, поскольку поддержка сильно различается.
Подсказки клиента
Для браузеров на основе Blink (Chromium, Edge, Brave, Vivaldi и других) альтернативой служат подсказки клиента user agent. При использовании подсказок клиента сервер заранее запрашивает сведения об устройстве у клиента через HTTP-заголовки или с помощью JavaScript API.
Подсказки клиента лучше подходят для определения браузеров на основе Blink, чем анализ UA: их подделывают не так часто, а предоставляемые ими сведения более компактны, надёжны и удобны для разбора. Тем не менее изменять функциональность сайта на основе подсказок клиента — плохая идея! По возможности следует использовать определение возможностей и постепенное улучшение, как описано выше.
Например, в механизме HTTP сервер отправляет заголовок Accept-CH вместе со списком заголовков, которые клиент должен включать в последующие запросы. Предположим, сервер отправляет клиенту следующий ответ:
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
Это означает, что в последующих запросах от клиента запрашиваются следующие заголовки:
-
Sec-CH-UA-Mobile: логическое значение, указывающее, является ли клиент мобильным устройством. -
Sec-CH-UA-Platform: платформа, на которой работает клиент («Windows», «Android» и так далее). -
Sec-CH-UA: название user agent и сведения о его основной версии.
Если клиент поддерживает подсказки клиента, в последующих запросах могут появиться подсказки клиента UA:
GET /my/page HTTP/1.1 Host: example.site Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96" Sec-CH-UA-Mobile: ?1 Sec-CH-UA-Platform: "Android"
Подробнее о подсказках клиента см. в статье Подсказки клиента HTTP. Прежде чем использовать эту возможность, ознакомьтесь с разделом Совместимость с браузерами.
Другие методы и принципы
- Постепенное улучшение
-
Этот метод проектирования предполагает разработку сайта «слоями» снизу вверх: сначала создаётся более простой слой, а затем возможности сайта последовательно расширяются за счёт добавления новых функций.
- Плавная деградация
-
Это подход сверху вниз: сначала создаётся максимально функциональный сайт со всеми необходимыми возможностями, а затем он адаптируется для работы в старых браузерах. Этот подход может быть сложнее и менее эффективен, чем постепенное улучшение, но в некоторых случаях он полезен.
Неподходящие причины для определения браузера
Если вы всё ещё рассматриваете определение браузера вместо определения возможностей и постепенного улучшения, проверьте, не руководствуетесь ли вы следующими (неподходящими) причинами:
- Вы пытаетесь обойти конкретную ошибку в определённой версии браузера
-
Скорее всего, вы не первый, кто с ней столкнулся. Эксперты или люди с другой точкой зрения могут подсказать, как лучше избежать ошибки или обойти её. Если проблема встречается редко, стоит проверить, сообщали ли о ней разработчикам браузера через систему отслеживания ошибок (Mozilla; WebKit; Blink; Opera). Разработчики браузеров действительно учитывают сообщения об ошибках, и ваше сообщение может помочь исправить проблему или предложить более надёжный способ её обхода.
- Отправка разного HTML в зависимости от браузера посетителя
-
Обычно это плохая идея, но в редких случаях такой подход необходим. Можно ли избежать этого, добавив несемантические элементы
<div>или<span>? Подумайте, действительно ли проблема заключается в дизайне: можно ли использовать постепенное улучшение или адаптивные макеты, чтобы отказаться от такого подхода? Решение должно зависеть от того, сколько усилий потребуется для точного определения UA по сравнению с переработкой HTML. - Попытка выяснить, поддерживает ли браузер посетителя определённую возможность
-
Сайту требуется определённая возможность, которую пока поддерживают не все браузеры, и вы хотите показывать пользователям несовместимых браузеров старую версию сайта с меньшим набором функций, которые, как вы знаете, будут работать. Это худшая причина для использования определения UA, поскольку со временем все браузеры, скорее всего, начнут поддерживать эту возможность. Кроме того, проверять таким способом поддержку каждой функции в каждом браузере непрактично.
Извлечение нужных частей строки UA
Если вы рассмотрели все описанные выше варианты, но всё ещё хотите в крайнем случае разобрать строку UA, советы из этого раздела помогут вам. К сожалению, структура различных частей строки user agent не унифицирована, поэтому дальше всё становится непросто.
Движок отображения
Браузеры с общим движком отображения отображают страницу одинаково: часто можно предположить, что то, что работает в одном браузере, будет работать и в другом. Сейчас используются три основных движка отображения: Blink, Gecko и WebKit.
В следующем примере строка Gecko/20100101 указывает на движок отображения Gecko, а «gecko-Trail» — это фиксированная строка 20100101, означающая «настольный компьютер»:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0
На сайтах часто определяют названия движков отображения, и многие user agent исторически добавляли названия других движков, чтобы сайты не блокировали их только на основании названия движка отображения. Поэтому важно избегать ложных срабатываний при определении движка отображения: этот метод особенно ненадёжен. Рассмотрим следующую строку UA, отправленную в Chrome 134 на macOS:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
| Движок | Должен содержать | Подробности |
|---|---|---|
| Blink | Chrome/xyz | |
| Gecko | Gecko/xyz | |
| WebKit | AppleWebKit/xyz | Браузеры WebKit добавляют строку like Gecko, которая может приводить к ложным срабатываниям для Gecko, если проверка выполнена недостаточно тщательно. |
| Presto | Opera/xyz | Устарел; Presto больше не используется в сборках браузера Opera начиная с версии 15 (см. «Blink»). |
| EdgeHTML | Edge/xyz | Устарел; EdgeHTML больше не используется в сборках браузера Edge начиная с версии 79 (см. «Blink»). |
Версия движка отображения
Большинство движков отображения указывают номер версии в токене RenderingEngine/VersionNumber; заметное исключение — Gecko. В следующем примере это строка rv:138.0, которая означает, что номер версии движка отображения — 138.0, то есть он совпадает с версией Firefox:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0
Название и версия браузера
Когда люди говорят, что им нужно «определение браузера», часто на самом деле им нужно «определение движка отображения». Обычно речь идёт об определении «Gecko» или «WebKit», а не «Firefox» или «Safari».
Большинство браузеров указывают название и версию в формате BrowserName/VersionNumber. Но поскольку в строке user agent в этом формате содержится не только название браузера, определить его название нельзя — можно лишь проверить, присутствует ли в строке нужное название. В следующем примере название браузера — это строка Firefox/138.0, которая указывает, что браузер называется Firefox, а версия программного обеспечения — 138.0:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0
Некоторые браузеры сообщают противоречивые сведения: например, Chrome указывает и Chrome, и Safari. Поэтому для определения Safari нужно проверить наличие строки Safari и отсутствие строки Chrome. Chromium часто также называет себя Chrome, а SeaMonkey — Firefox.
Будьте осторожны при использовании регулярных выражений для части BrowserName: строки user agent также содержат строки, не соответствующие синтаксису «ключ/значение». Например, в Safari и Chrome есть строка like Gecko.
| Название браузера | Должен содержать | Не должен содержать |
|---|---|---|
| Firefox | Firefox/xyz | Seamonkey/xyz |
| Seamonkey | Seamonkey/xyz | |
| Chrome | Chrome/xyz |
Chromium/xyz или Edg.*/xyz
|
| Chromium | Chromium/xyz | |
| Safari |
Safari/xyz * |
Chrome/xyz или Chromium/xyz
|
| Opera 15+ (движок на основе Blink) | OPR/xyz | |
| Opera 12- (движок на основе Presto) | Opera/xyz |
* Safari указывает два номера версии: технический — в токене Safari/xyz, а удобный для пользователей — в токене Version/xyz.
Разумеется, нет никаких гарантий, что в определённых случаях другой браузер не подделает эти значения. Именно поэтому определение браузера по строке user agent ненадёжно и должно выполняться только с проверкой номера версии (подделать сведения о более старой версии менее вероятно).
Определение операционной системы
Операционная система указывается в большинстве строк UA (за исключением платформ, не ориентированных на веб), но формат различается. Это фиксированная строка между двумя точками с запятой в части комментария User Agent; эти строки уникальны для каждого браузера.
В них указывается ОС, а часто и её версия, а также сведения об оборудовании (32- или 64-разрядная система, Intel/PPC для Mac или архитектура процессора x86/ARM для компьютеров с Windows). В следующем примере это строка Intel Mac OS X 10.15:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0
Во всех случаях эти строки могут меняться, поэтому используйте их только вместе с определением уже выпущенных браузеров, чтобы заранее знать соответствующие шаблоны. Чтобы адаптировать код при выпуске новых версий браузеров, можно проводить опрос посетителей или изучать строки UA.
Мобильное устройство, планшет или компьютер
Чаще всего анализ user agent выполняют, чтобы определить тип устройства, на котором работает браузер.
- Никогда не предполагайте, что браузер или движок отображения работает только на устройствах одного типа. В частности, не полагайтесь на то, что у разных браузеров или движков отображения разные настройки по умолчанию.
- Никогда не используйте токен ОС, чтобы определить, работает ли браузер на мобильном устройстве, планшете или компьютере. Одна и та же ОС может работать на устройствах разных типов (например, Android используется и на планшетах, и на телефонах).
В следующей таблице приведены способы, которыми распространённые разработчики браузеров обозначают работу своих браузеров на мобильном устройстве:
| Браузер | Правило | Пример |
|---|---|---|
| Mozilla (Gecko, Firefox) |
Mobile или Tablet внутри комментария. | Mozilla/5.0 (Android 15; Mobile; rv:136.0) Gecko/136.0 Firefox/136.0 |
| На основе WebKit (Android, Safari) |
токен Mobile Safari вне комментария. | Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 |
| На основе Blink (Chromium, Google Chrome, Opera 15+, Edge на Android) |
токен Mobile Safari вне комментария. | Mozilla/5.0 (Linux; Android 4.4.2; Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047 |
| Edge на Windows 10 Mobile |
токены Mobile/xyz и Edge/ вне комментария. | Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Mobile Safari/537.36 Edge/16.16299 |
Вкратце, можно искать строку Mobi в любом месте строки UA. Если устройство достаточно большое и в его строке нет отметки Mobi, следует показывать версию сайта для настольных устройств (которая, в соответствии с рекомендациями, в любом случае должна поддерживать сенсорный ввод, поскольку у настольных устройств могут быть сенсорные экраны).
См. также
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Browser_detection_using_the_user_agent