Browser detection methods
Browser Detection Methods
Browser detection is a common requirement in front-end development, used to handle compatibility issues between different browsers or provide specific features. The main methods include user agent string analysis, feature detection, and modern API detection.
User Agent String Detection
Obtaining browser information through navigator.userAgent
is the most traditional method. Although it can be tampered with, it remains effective for basic identification.
const userAgent = navigator.userAgent;
// Detect Chrome
if (userAgent.indexOf('Chrome') > -1) {
console.log('Chrome browser');
}
// Detect Firefox
if (userAgent.indexOf('Firefox') > -1) {
console.log('Firefox browser');
}
// Detect Safari
if (userAgent.indexOf('Safari') > -1 && userAgent.indexOf('Chrome') === -1) {
console.log('Safari browser');
}
// Detect Edge
if (userAgent.indexOf('Edg') > -1) {
console.log('Microsoft Edge browser');
}
A more complete detection solution can combine regular expressions:
const browser = {
isIE: /Trident|MSIE/.test(userAgent),
isEdge: /Edg/.test(userAgent),
isFirefox: /Firefox/.test(userAgent),
isChrome: /Chrome/.test(userAgent) && !/Edg/.test(userAgent),
isSafari: /Safari/.test(userAgent) && !/Chrome/.test(userAgent)
};
Feature Detection Method
Compared to user agent detection, feature detection is more reliable, determining by checking whether the browser supports specific APIs or features.
// Detect WebP image support
function supportsWebp() {
const elem = document.createElement('canvas');
return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0;
}
// Detect Fetch API
if (window.fetch) {
console.log('Supports Fetch API');
} else {
console.log('Does not support Fetch API, requires polyfill');
}
// Detect CSS Grid layout support
if (CSS.supports('display', 'grid')) {
document.documentElement.classList.add('cssgrid');
} else {
document.documentElement.classList.add('no-cssgrid');
}
Modern Detection Techniques
As browsers standardize, more precise detection methods have emerged:
// Detect ES6 module support
const supportsModules = 'noModule' in HTMLScriptElement.prototype;
// Detect Web Components support
const supportsWebComponents = 'customElements' in window;
// Detect Service Worker support
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
// Detect WebGL support
function detectWebGL() {
try {
const canvas = document.createElement('canvas');
return !!(
window.WebGLRenderingContext &&
(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))
);
} catch (e) {
return false;
}
}
Browser Version Detection
Sometimes detection for specific browser versions is needed:
// Get Chrome major version number
const chromeVersion = userAgent.match(/Chrome\/(\d+)/)?.[1];
// Get Firefox version
const firefoxVersion = userAgent.match(/Firefox\/(\d+)/)?.[1];
// Detect IE11 and below versions
const isIE11OrBelow = !!window.MSInputMethodContext && !!document.documentMode;
Mobile Device Detection
Distinguish between mobile and desktop browsers:
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
// More precise touch device detection
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
// Detect iOS devices
const isIOS = /iPad|iPhone|iPod/.test(userAgent) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
Performance Feature Detection
Detect browser performance-related features:
// Detect hardware acceleration status
const supportsHardwareAcceleration =
'WebGLRenderingContext' in window &&
'getExtension' in WebGLRenderingContext.prototype;
// Detect WebAssembly support
const supportsWasm = 'WebAssembly' in window;
// Detect Web Workers support
const supportsWorkers = 'Worker' in window;
Private Mode Detection
Detect whether the browser is in private browsing mode:
function isPrivateBrowsing() {
return new Promise(resolve => {
const fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fs) return resolve(false);
fs(window.TEMPORARY, 100, () => resolve(false), () => resolve(true));
});
}
// Usage example
isPrivateBrowsing().then(isPrivate => {
console.log(isPrivate ? 'Private mode' : 'Normal mode');
});
Browser Engine Detection
Identify the underlying rendering engine:
const engine = {
isWebKit: 'WebkitAppearance' in document.documentElement.style,
isGecko: 'MozAppearance' in document.documentElement.style,
isBlink: 'chrome' in window && 'CSS' in window,
isTrident: 'msWriteProfilerMark' in window
};
Network Connection Detection
Detect network status and type:
// Detect network connection status
const isOnline = navigator.onLine;
// Detect connection type (requires browser support)
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
if (connection) {
console.log('Network type:', connection.type);
console.log('Effective type:', connection.effectiveType);
console.log('Download speed:', connection.downlink + 'Mb/s');
}
// Listen for network changes
if (connection) {
connection.addEventListener('change', () => {
console.log('Network status changed:', connection.effectiveType);
});
}
Browser Language Detection
Get the user's preferred language:
// Get browser language settings
const userLanguage = navigator.language || navigator.userLanguage;
// Get all supported languages
const languages = navigator.languages || [navigator.language];
// Detect Chinese users
const isChineseUser = /^zh/.test(userLanguage);
Browser Plugin Detection
Detect installed browser plugins:
// Detect Flash plugin
function hasFlash() {
try {
const flash = navigator.plugins['Shockwave Flash'];
return !!flash;
} catch (e) {
return false;
}
}
// Detect PDF viewer
const hasPDFViewer = navigator.mimeTypes['application/pdf'] !== undefined;
// List all plugins
const plugins = Array.from(navigator.plugins).map(plugin => ({
name: plugin.name,
description: plugin.description,
filename: plugin.filename
}));
Browser Viewport Detection
Get browser window information:
// Detect viewport dimensions
const viewportWidth = Math.max(
document.documentElement.clientWidth || 0,
window.innerWidth || 0
);
const viewportHeight = Math.max(
document.documentElement.clientHeight || 0,
window.innerHeight || 0
);
// Detect device pixel ratio
const pixelRatio = window.devicePixelRatio || 1;
// Detect screen orientation
const orientation = window.screen.orientation ||
window.screen.mozOrientation ||
window.screen.msOrientation;
if (orientation) {
console.log('Current orientation:', orientation.type);
}
Browser Storage Detection
Detect the availability of various storage APIs:
// Detect localStorage availability
function hasLocalStorage() {
try {
const test = '__storage_test__';
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
// Detect IndexedDB support
const hasIndexedDB = 'indexedDB' in window;
// Detect WebSQL support (deprecated)
const hasWebSQL = 'openDatabase' in window;
// Detect Cookie support
function hasCookies() {
document.cookie = 'testcookie=1';
return document.cookie.indexOf('testcookie=') !== -1;
}
Browser Security Feature Detection
Detect security-related features:
// Detect HTTPS status
const isSecure = window.location.protocol === 'https:';
// Detect Content Security Policy
const hasCSP = 'securityPolicy' in document ||
'webkitSecurityPolicy' in document;
// Detect Referrer Policy support
const hasReferrerPolicy = 'referrerPolicy' in document.createElement('a');
// Detect mixed content auto-upgrade
const hasMixedContentAutoUpgrade =
'upgradeInsecureRequests' in document.createElement('meta');
Browser API Compatibility Detection
Detect compatibility with new APIs:
// Detect Intersection Observer API
const hasIntersectionObserver = 'IntersectionObserver' in window;
// Detect Resize Observer API
const hasResizeObserver = 'ResizeObserver' in window;
// Detect Payment Request API
const hasPaymentRequest = 'PaymentRequest' in window;
// Detect Web Share API
const hasWebShare = 'share' in navigator;
// Detect Web Bluetooth API
const hasWebBluetooth = 'bluetooth' in navigator;
Browser Graphics Capability Detection
Detect graphics-related features:
// Detect Canvas support
const hasCanvas = !!document.createElement('canvas').getContext;
// Detect SVG support
const hasSVG = !!document.createElementNS &&
!!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect;
// Detect WebGL version
function getWebGLVersion() {
try {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) return 0;
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
return debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : 1;
} catch (e) {
return 0;
}
}
Browser Media Capability Detection
Detect media-related features:
// Detect video format support
function canPlayVideoType(type) {
const video = document.createElement('video');
return !!video.canPlayType(type).replace(/no/, '');
}
// Detect Audio API
const hasWebAudio = 'AudioContext' in window ||
'webkitAudioContext' in window;
// Detect media device access
const hasMediaDevices = 'mediaDevices' in navigator &&
'getUserMedia' in navigator.mediaDevices;
// Detect screen sharing API
const hasScreenCapture = 'getDisplayMedia' in navigator.mediaDevices;
Browser Input Method Detection
Detect input method-related status:
// Detect IME status
const isIMEActive = () => {
const input = document.createElement('input');
input.style.position = 'fixed'; // Prevent layout changes
document.body.appendChild(input);
input.focus();
const initialWidth = input.offsetWidth;
input.value = 'あ'; // Trigger IME input
const imeWidth = input.offsetWidth;
document.body.removeChild(input);
return imeWidth !== initialWidth;
};
// Detect virtual keyboard status
const isVirtualKeyboardVisible = () => {
return window.innerHeight < window.screen.height;
};
Browser Extension Detection
Detect the presence of browser extensions:
// Detect AdBlock and other ad blockers
function detectAdBlocker() {
return new Promise(resolve => {
const ad = document.createElement('div');
ad.innerHTML = ' ';
ad.className = 'adsbox';
ad.style.position = 'absolute';
ad.style.left = '-999px';
ad.style.height = '1px';
document.body.appendChild(ad);
window.setTimeout(() => {
const isBlocked = ad.offsetHeight === 0;
document.body.removeChild(ad);
resolve(isBlocked);
}, 100);
});
}
Browser Automation Detection
Detect if running in an automated testing environment:
// Detect Headless Chrome
const isHeadlessChrome = () => {
return navigator.webdriver === true ||
/HeadlessChrome/.test(navigator.userAgent);
};
// Detect Puppeteer
const isPuppeteer = () => {
return navigator.userAgent.includes('Puppeteer');
};
// Detect Selenium
const isSelenium = () => {
return navigator.webdriver === true &&
!navigator.userAgent.includes('HeadlessChrome');
};
Browser Memory Detection
Get browser memory information:
// Detect device memory (requires browser support)
const deviceMemory = navigator.deviceMemory || 0;
// Detect performance memory API
if ('performance' in window && 'memory' in performance) {
console.log('Used JS heap:', performance.memory.usedJSHeapSize);
console.log('JS heap size limit:', performance.memory.jsHeapSizeLimit);
}
// Detect memory pressure API
const hasMemoryPressure = 'memory' in navigator &&
'pressure' in navigator.memory;
Browser Permission Detection
Detect various permission states:
// Detect notification permission
const notificationPermission = Notification.permission;
// Detect geolocation permission
navigator.permissions.query({name: 'geolocation'})
.then(result => {
console.log('Geolocation permission:', result.state);
});
// Detect camera permission
async function checkCameraPermission() {
try {
const stream = await navigator.mediaDevices.getUserMedia({video: true});
stream.getTracks().forEach(track => track.stop());
return true;
} catch (e) {
return false;
}
}
Browser Battery Status Detection
Detect device battery information:
// Detect Battery API
if ('getBattery' in navigator) {
navigator.getBattery().then(battery => {
console.log('Battery level:', battery.level * 100 + '%');
console.log('Charging status:', battery.charging ? 'Charging' : 'Not charging');
battery.addEventListener('levelchange', () => {
console.log('Battery level changed:', battery.level * 100 + '%');
});
battery.addEventListener('chargingchange', () => {
console.log('Charging status changed:', battery.charging ? 'Charging' : 'Not charging');
});
});
}
Browser Payment Method Detection
Detect supported payment methods:
// Detect Payment Request API supported payment methods
async function getPaymentMethods() {
if (!window.PaymentRequest) return [];
try {
const request = new PaymentRequest(
[{supportedMethods: 'basic-card'}],
{total: {label: 'Total', amount: {currency: 'USD', value: '0.01'}}}
);
const methods = await request.canMakePayment();
return methods;
} catch (e) {
return [];
}
}
// Detect specific payment method
async function supportsPaymentMethod(method) {
try {
const request = new PaymentRequest(
[{supportedMethods: method}],
{total: {label: 'Total', amount: {currency: 'USD', value: '0.01'}}}
);
return await request.canMakePayment();
} catch (e) {
return false;
}
}
Browser WebRTC Detection
Detect WebRTC-related features:
// Detect WebRTC support
const hasWebRTC = 'RTCPeerConnection' in window ||
'webkitRTCPeerConnection' in window ||
'mozRTCPeerConnection' in window;
// Get WebRTC IP leak information
function getRTCPeerConnectionIceServers() {
const config = {iceServers: [{urls: 'stun:stun.l.google.com:19302'}]};
const pc = new (window.RTCPeerConnection ||
window.webkitRTCPeerConnection ||
window.mozRTCPeerConnection)(config);
return new Promise(resolve => {
pc.createDataChannel('');
pc.createOffer().then(offer => pc.setLocalDescription(offer));
pc.onicecandidate = ice => {
if (!ice.candidate) {
const candidates = pc.localDescription.sdp.match(/a=candidate:.+/g) || [];
resolve(candidates);
}
};
});
}
Browser WebXR Detection
Detect virtual reality and augmented reality support:
// Detect WebXR API
async function checkWebXRSupport() {
if (!navigator.xr) return 'unsupported';
try {
const supported = await navigator.xr.isSessionSupported('immersive-vr');
return supported ? 'immersive-vr' : 'unsupported';
} catch (e) {
return 'unsupported';
}
}
// Detect AR support
async function checkARSupport() {
if (!navigator.xr) return false;
try {
return await navigator.xr.isSessionSupported('immersive-ar');
} catch (e) {
return false;
}
}
Browser WebAssembly Detection
Detect WebAssembly support:
// Detect WebAssembly support
const hasWasm = typeof WebAssembly === 'object' &&
typeof WebAssembly.instantiate === 'function';
// Detect specific WebAssembly features
async function checkWasmFeatures() {
if (!hasWasm) return {};
try {
const result = await WebAssembly.validate(new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00
]));
return {
simd: WebAssembly.validate(new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b
])),
threads: WebAssembly.validate(new Uint8Array([
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn