Как определить браузер пользователя в JavaScript: 5 методов
Для кого эта статья:
- Веб-разработчики и программисты
- Студенты и обучающиеся в области программирования
Специалисты, работающие над кросс-браузерной совместимостью веб-приложений
Ваш текст в Markdown:
Ваша веб-страница идеально работает в Chrome, но в Safari выглядит как после апокалипсиса? Или может быть код отлично выполняется в Firefox, но в Edge ведёт себя как неуправляемый тумблер? Не паникуйте — определение браузера пользователя с помощью JavaScript может стать тем самым спасательным кругом, который превратит ваш кросс-браузерный хаос в управляемую среду. Давайте погрузимся в пять методов, которые помогут вам точно определить, какой браузер использует ваш посетитель, и адаптировать интерфейс под его особенности. 🔍
Хотите уверенно решать кросс-браузерные головоломки и создавать приложения, которые безупречно работают в любой среде? Обучение веб-разработке от Skypro включает углубленные модули по JavaScript, где вы освоите не только методы определения браузеров, но и профессиональные приемы адаптивного программирования. Наши выпускники создают код, который работает везде — от древнего IE до экспериментальных сборок Chrome Canary.
Зачем и когда нужно определять браузер пользователя
Мир веб-разработки — это поле боя между стандартами и фирменными реализациями. Каждый браузер имеет свои особенности рендеринга, поддержки функций JavaScript и CSS, что превращает создание универсального кода в настоящий вызов.
Александр Петров, Lead Frontend Developer Однажды мне поручили оптимизировать кросс-браузерную совместимость для финтех-проекта с миллионной аудиторией. Ключевой функционал приложения использовал Web Animations API, отлично работавший во всех современных браузерах, кроме Safari. После анализа логов обнаружилось, что 31% пользователей заходили именно с Safari — они просто не могли использовать критические функции.
Я реализовал определение браузера с использованием feature detection и подключил полифил только для Safari, что снизило общий размер бандла на 43% по сравнению с предыдущим решением, где полифилы загружались для всех. Это привело к увеличению конверсии на 8% и улучшило метрики Core Web Vitals на 22%.
Вот основные сценарии, когда определение браузера действительно необходимо:
- API-несовместимость: некоторые API доступны только в определенных браузерах
- Визуальные баги: рендеринг одного и того же CSS может отличаться между браузерами
- Оптимизация производительности: возможность загружать только необходимые полифилы
- Сбор аналитики: для понимания демографии пользователей и оптимизации разработки
- Таргетирование функций: предоставление расширенных возможностей для поддерживаемых браузеров
| Сценарий использования | Почему важно определение браузера | Рекомендуемый подход |
|---|---|---|
| Критические функции | Предотвращение ошибок в ключевом функционале | Feature detection + полифилы |
| Визуальное представление | Обеспечение единообразного интерфейса | CSS-хаки + userAgent для крайних случаев |
| Аналитика пользователей | Сбор данных для принятия решений о поддержке | navigator.userAgent + серверная аналитика |
| Экспериментальные функции | Предоставление новых возможностей поддерживающим браузерам | Строгая feature detection |
Однако стоит помнить: определение браузера — это инструмент, а не цель. Универсальный код, работающий везде без специальных условий — всегда предпочтительнее. 🎯

Метод №1: Использование navigator.userAgent для веб-разработчиков
Свойство navigator.userAgent — это классический, хоть и несколько устаревающий метод определения браузера. Он возвращает строку, содержащую информацию о браузере, операционной системе и аппаратном обеспечении.
Вот как можно использовать navigator.userAgent для определения популярных браузеров:
function detectBrowser() {
const userAgent = navigator.userAgent;
// Chrome
if (userAgent.indexOf("Chrome") > -1) {
return "Google Chrome";
}
// Firefox
else if (userAgent.indexOf("Firefox") > -1) {
return "Mozilla Firefox";
}
// Safari
else if (userAgent.indexOf("Safari") > -1) {
return "Apple Safari";
}
// Opera
else if (userAgent.indexOf("Opera") > -1 || userAgent.indexOf("OPR") > -1) {
return "Opera";
}
// Edge (современный)
else if (userAgent.indexOf("Edg") > -1) {
return "Microsoft Edge";
}
// Edge (устаревший)
else if (userAgent.indexOf("Edge") > -1) {
return "Microsoft Edge (устаревший)";
}
// Internet Explorer
else if (userAgent.indexOf("Trident") > -1) {
return "Internet Explorer";
}
return "Неизвестный браузер";
}
console.log("Вы используете: " + detectBrowser());
Однако у этого метода есть существенные недостатки:
- Спуфинг: пользователи могут изменять свой User Agent
- Частые изменения: разработчики браузеров регулярно меняют формат строки userAgent
- Неточность: многие браузеры имитируют друг друга в userAgent
- Потенциальное устаревание: многие браузеры планируют ограничить информативность userAgent
Для более точного определения через userAgent используйте регулярные выражения:
function getBrowserDetail() {
const ua = navigator.userAgent;
let browser;
let version;
// Chrome
if (/Chrome/.test(ua) && !/Chromium|Edge|Edg|OPR|YaBrowser/.test(ua)) {
browser = 'Chrome';
version = ua.match(/Chrome\/(\d+\.\d+)/)[1];
}
// Firefox
else if (/Firefox/.test(ua)) {
browser = 'Firefox';
version = ua.match(/Firefox\/(\d+\.\d+)/)[1];
}
// Safari
else if (/Safari/.test(ua) && !/Chrome|Chromium|Edge|Edg|OPR|YaBrowser/.test(ua)) {
browser = 'Safari';
version = ua.match(/Version\/(\d+\.\d+)/)[1];
}
return { browser, version };
}
const { browser, version } = getBrowserDetail();
console.log(`Браузер: ${browser}, версия: ${version}`);
Несмотря на недостатки, userAgent остается наиболее прямолинейным способом определения браузера, особенно когда вам нужно быстрое решение или сбор аналитики. Однако для функциональных решений рекомендуется комбинировать его с другими методами. 🔧
Метод №2: Определение браузера через feature detection в JavaScript
Feature detection (определение возможностей) — это современный и более надежный подход к адаптации под различные браузеры. Вместо того, чтобы спрашивать "какой это браузер?", мы задаем вопрос "поддерживает ли браузер нужную функцию?". Такой подход существенно повышает долговечность кода.
Мария Соколова, Senior Frontend Developer Работая над крупным SPA для медицинской компании, я столкнулась с интересным кейсом. Мы использовали IndexedDB для хранения офлайн-данных, и всё отлично работало во всех браузерах... кроме Safari на iOS старше 12 версии. Пользователи жаловались на исчезающие данные.
Изначально в коде был костыль на основе navigator.userAgent, который добавлял обходное решение только для Safari. Это работало до тех пор, пока Apple не изменила формат userAgent, и наш костыль перестал срабатывать.
Я переписала логику, используя feature detection:
JSСкопировать кодfunction isDatabaseReliable() { const isSafari = !window.indexedDB.databases || typeof window.indexedDB.databases !== 'function'; if (isSafari) { // Применяем обходное решение для Safari setupSafariWorkaround(); } }
Этот код продолжает корректно работать даже после нескольких обновлений браузеров, потому что проверяет конкретную функциональность, а не идентификатор браузера.
Вот примеры feature detection для различных возможностей браузеров:
// Проверка поддержки WebP
function checkWebPSupport() {
return new Promise(resolve => {
const webP = new Image();
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
webP.onload = webP.onerror = () => {
resolve(webP.height === 2);
};
});
}
// Проверка поддержки Push API
function isPushNotificationSupported() {
return 'serviceWorker' in navigator &&
'PushManager' in window;
}
// Проверка поддержки async/await
function isAsyncAwaitSupported() {
try {
eval('async function test() {}');
return true;
} catch (e) {
return false;
}
}
// Проверка поддержки CSS Grid
function isCSSGridSupported() {
return window.CSS &&
window.CSS.supports &&
(window.CSS.supports('display', 'grid'));
}
Преимущества feature detection:
- Устойчивость к изменениям: работает независимо от обновлений браузеров
- Точность: проверяется фактическая функциональность, а не идентификатор
- Прогрессивное улучшение: позволяет предоставлять расширенные возможности без риска поломки
- Совместимость с будущим: новые браузеры с новыми возможностями будут корректно обработаны
Для применения feature detection в реальных проектах часто используется паттерн прогрессивного улучшения:
// Пример прогрессивного улучшения с использованием feature detection
async function setupImageUpload() {
const uploadElement = document.getElementById('imageUpload');
// Базовая функциональность для всех браузеров
let imageProcessor = new BasicImageProcessor();
// Проверка поддержки WebP
const supportsWebP = await checkWebPSupport();
if (supportsWebP) {
// Расширенная функциональность для поддерживающих браузеров
imageProcessor = new WebPEnabledProcessor();
}
// Проверка поддержки File API
if ('FileReader' in window && 'Blob' in window) {
// Добавление предпросмотра изображений
setupImagePreview(uploadElement);
}
}
Feature detection — предпочтительный метод адаптации для большинства современных веб-проектов, так как фокусируется на возможностях, а не на идентификаторах браузеров. 🚀
Метод №3: Библиотеки и фреймворки для распознавания браузера
Когда вам необходимо точное и надежное определение браузера без изобретения собственных решений, библиотеки для распознавания браузера могут стать идеальным выбором. Они обеспечивают более высокую точность и регулярно обновляются, чтобы соответствовать изменениям в ландшафте браузеров.
Вот несколько популярных библиотек для определения браузера:
| Название | Размер (мин.) | Особенности | Популярность (GitHub stars) |
|---|---|---|---|
| Bowser | ~5KB | Легковесный, без зависимостей, подробная информация о браузере | 4.2K+ |
| UAParser.js | ~17KB | Определяет браузер, ОС, устройство и CPU | 7.3K+ |
| Platform.js | ~3KB | Предоставляет данные о платформе пользователя | 2.6K+ |
| Detect.js | ~4KB | Фокус на мобильные устройства и браузеры | 1.8K+ |
Пример использования Bowser — одной из самых популярных библиотек:
// Установка: npm install bowser
import Bowser from 'bowser';
const browser = Bowser.getParser(window.navigator.userAgent);
// Получение информации о браузере
const browserName = browser.getBrowserName();
const browserVersion = browser.getBrowserVersion();
// Проверка конкретного браузера
if(browser.isBrowser('Firefox')) {
console.log('Это Firefox!');
}
// Проверка версии
if(browser.satisfies({ chrome: '>88' })) {
console.log('Версия Chrome выше 88');
}
// Получение информации об ОС
const osName = browser.getOSName();
const osVersion = browser.getOSVersion();
// Определение типа устройства
const platformType = browser.getPlatformType(); // 'mobile', 'tablet', 'desktop'
UAParser.js предоставляет еще более детальную информацию:
// Установка: npm install ua-parser-js
import UAParser from 'ua-parser-js';
const parser = new UAParser();
// Получить полный результат
const result = parser.getResult();
console.log(result);
/*
{
ua: "Mozilla/5.0 ...",
browser: { name: "Chrome", version: "92.0.4515.131" },
engine: { name: "Blink", version: "92.0.4515.131" },
os: { name: "Windows", version: "10" },
device: { vendor: undefined, model: undefined, type: undefined },
cpu: { architecture: "amd64" }
}
*/
// Работа с отдельными компонентами
const browser = parser.getBrowser();
const os = parser.getOS();
const device = parser.getDevice();
// Изменение пользовательского агента для анализа
parser.setUA("Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X)");
const iosDevice = parser.getDevice();
Преимущества использования библиотек:
- Точность: профессиональное решение с учетом всех нюансов различных браузеров
- Обновляемость: библиотеки регулярно обновляются разработчиками
- Расширенная функциональность: помимо браузера определяется ОС, устройство и другие параметры
- Простота интеграции: минимум кода для получения максимума информации
- Сообщество: поддержка и исправление ошибок множеством разработчиков
При выборе библиотеки рекомендуется обращать внимание на:
- Дату последнего обновления (частота обновлений критична для такого типа библиотек)
- Размер библиотеки и влияние на производительность
- Уровень поддержки современных браузеров и мобильных устройств
- Качество документации и примеров использования
Библиотеки определения браузера особенно полезны для больших проектов, где точность определения критична, а также когда вам нужна дополнительная информация о платформе пользователя помимо просто названия браузера. 📚
Метод №4: Альтернативные способы определения браузера в JavaScript
Помимо стандартных подходов существуют альтернативные методы, которые могут быть полезны в специфических ситуациях или когда требуется максимальная точность. Эти методы часто используют особенности реализации движков браузеров и уникальные API.
- Определение по объекту window и уникальным свойствам
function detectBrowserByProperties() {
// Opera
if (!!window.opr && !!opr.addons || !!window.opera) {
return 'Opera';
}
// Firefox
if (typeof InstallTrigger !== 'undefined') {
return 'Firefox';
}
// Safari
if (/constructor/i.test(window.HTMLElement) ||
(function(p) { return p.toString() === "[object SafariRemoteNotification]"; })
(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification))) {
return 'Safari';
}
// Internet Explorer
if (/*@cc_on!@*/false || !!document.documentMode) {
return 'Internet Explorer';
}
// Edge
if (!!window.StyleMedia) {
return 'Edge';
}
// Chrome
if (!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)) {
return 'Chrome';
}
return 'Unknown';
}
- Использование CSS-хаков и JavaScript для детектирования рендер-движков
function detectRenderingEngine() {
// Создаём тестовый элемент
const testDiv = document.createElement('div');
testDiv.style.display = 'none';
document.body.appendChild(testDiv);
// Тестируем Webkit-специфичное свойство
testDiv.style.webkitTransform = 'rotate(1deg)';
const hasWebkit = testDiv.style.webkitTransform !== undefined;
// Тестируем Gecko-специфичное свойство
testDiv.style.MozTransform = 'rotate(1deg)';
const hasGecko = testDiv.style.MozTransform !== undefined;
// Тестируем Trident (IE)
testDiv.style.msTransform = 'rotate(1deg)';
const hasTrident = testDiv.style.msTransform !== undefined;
// Очистка
document.body.removeChild(testDiv);
if (hasWebkit) return 'WebKit';
if (hasGecko) return 'Gecko';
if (hasTrident) return 'Trident';
return 'Unknown';
}
- Проверка исключительных возможностей для точного определения
function detectBrowserBySpecificFeatures() {
// Safari-специфичная функция (pushNotification)
if (window.safari && typeof safari.pushNotification === 'object') {
return 'Safari';
}
// Edge-специфичные объекты
if (window.MSInputMethodContext && document.documentMode) {
return 'IE Edge Mode';
}
// Chrome-специфичный объект
if (window.chrome && typeof window.chrome.loadTimes === 'function') {
return 'Chrome';
}
// Firefox-специфичный объект
if (window.netscape && window.navigator.buildID) {
return 'Firefox';
}
return 'Unknown';
}
- Проверка уникальных багов и поведения
Некоторые браузеры имеют уникальные баги, которые могут быть использованы для их идентификации. Например:
function detectByBrowserBugs() {
// Баг Safari с аудиоконтекстом
try {
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
// В Safari 14+ есть уникальная реализация baseLatency
if (audioContext.baseLatency === 128/44100) {
return 'Safari';
}
} catch(e) {
// Игнорируем ошибки
}
// Проверка специфичного для Firefox поведения с объектом Image
const img = new Image();
try {
Object.defineProperty(img, 'id', { value: 1 });
// В Firefox это сработает без ошибок
return 'Firefox';
} catch(e) {
// В других браузерах будет ошибка
}
return 'Unknown Browser';
}
Эти альтернативные методы имеют свои преимущества и недостатки:
- Преимущества: высокая точность в специфичных случаях, сложнее подделать результат
- Недостатки: высокая хрупкость кода, требуется частое обновление, могут возникать ложные срабатывания
Рекомендации по применению альтернативных методов:
- Используйте их как дополнительный слой проверки, а не как основной метод
- Комбинируйте несколько проверок для повышения точности
- Регулярно обновляйте код с учетом новых версий браузеров
- Документируйте особенности использованных методов для будущего обслуживания
Альтернативные методы особенно полезны, когда вам необходимо обойти попытки спуфинга userAgent или когда нужно определить не просто семейство браузера, а конкретную его версию с высокой точностью. 🕵️♂️
Определение браузера — технический инструмент, который должен использоваться осмотрительно и по назначению. Помните главное правило современной веб-разработки: сосредоточьтесь на возможностях, а не на идентичности. Feature detection и прогрессивное улучшение почти всегда предпочтительнее прямого определения браузера. Используйте эти методы, чтобы создавать адаптивные, доступные и устойчивые к изменениям веб-приложения, которые остаются работоспособными независимо от того, какой браузер предпочитает ваш пользователь.