JavaScript高级程序设计笔记 13
第13章 客户端检测
1. 客户端检测的必要性
- 不同浏览器、不同版本对 Web API 的支持存在差异。
- 常见检测方式:能力检测、用户代理检测、怪癖检测。
2. 能力检测
2.1 定义
- 测试浏览器是否支持某个特性(方法/属性),而不是猜测哪个浏览器。
- 最可靠、最推荐的方式。
2.2 基本原则
- 先检测最常用的特性。
- 检测实际要用到的特性,而非某个库或整个功能集。
- 不要假设存在某个特性后其他特性也存在。
// 好的做法
if (element.addEventListener) {
element.addEventListener('click', handler, false);
} else if (element.attachEvent) {
element.attachEvent('onclick', handler);
} else {
element.onclick = handler;
}
2.3 常见检测模式
- 检测 DOM 方法:
typeof document.createElement('div').getBoundingClientRect === 'function'。 - 检测 ES6 特性:
typeof Set !== 'undefined'。
3. 用户代理检测
3.1 定义
- 通过
navigator.userAgent字符串识别浏览器、引擎、操作系统等。 - 不可靠:可被伪造,但仍是某些场景的最后手段(如针对特定版本的 bug 修复)。
3.2 常用用户代理嗅探库
- 实际开发中通常使用成熟的库(如
bowser、ua-parser-js)而非手写正则。
3.3 手写识别模式示例(简版)
let ua = navigator.userAgent;
if (ua.includes('Chrome')) {
// Chrome
} else if (ua.includes('Firefox')) {
// Firefox
} else if (ua.includes('Safari') && !ua.includes('Chrome')) {
// Safari
}
4. 软件与硬件检测
4.1 软件检测(不常用)
- 检测浏览器是否安装特定插件(
navigator.plugins)。 - 检测语言、网络状态等。
4.2 硬件检测(现代 API)
navigator.hardwareConcurrency:CPU 核心数。navigator.deviceMemory:设备内存(GB,部分浏览器)。navigator.connection:网络信息(Network Information API,实验性)。
5. 检测策略决策树
- 优先使用能力检测(绝大多数情况)。
- 能力检测不足时,使用用户代理检测作为回退(如已知某个浏览器版本存在 bug)。
- 避免过度依赖用户代理字符串。
6. 常见面试题速查
-
什么是能力检测?
→ 测试浏览器是否支持某个特定的方法/属性,而非识别浏览器品牌。 -
能力检测与用户代理检测哪个更可靠?
→ 能力检测更可靠,用户代理可被伪造。 -
用户代理检测在什么场景下仍有必要?
→ 遇到特定浏览器版本的 bug,且无法通过能力检测区分时。 -
如何检测浏览器是否支持 ES6 的 Promise?
→typeof Promise !== 'undefined' && Promise.toString().includes('[native code]')(简单检测通常足够)。 -
如何检测浏览器是否支持触摸事件?
→'ontouchstart' in window。 -
检测浏览器是否支持 WebGL?
→ 尝试获取canvas.getContext('webgl')或canvas.getContext('experimental-webgl')。 -
navigator.plugins能检测什么?
→ 列出已安装的浏览器插件(不含 Flash,需单独检测)。 -
为什么不能完全相信 userAgent?
→ 用户可以修改浏览器字符串,且某些浏览器伪装成其他浏览器。 -
如何处理不同浏览器的 CSS 前缀?
→ 可使用能力检测动态添加前缀,或使用 CSS 预处理器/PostCSS。 -
什么是怪癖检测?
→ 检测浏览器特定的实现 bug(如 IE 中某个属性行为异常),通常通过执行代码并观察结果判断。

浙公网安备 33010602011771号