JavaScript 客户端检测——“用户代理检测”的注意要点 - 前端学习笔记
用户代理检测
通过 JavaScript 的 navigator.userAgent 属性访问。在服务器端,通过检测用户代理字符串来确定用户使用的浏览器是一种常用的做法;但在客户端,用户代理检测一般为最低优先级。
用户代理字符串检测技术
首先要确定你需要多么具体的浏览器信息。然后在使用代码进行检测。
识别呈现引擎
原理
确切知道浏览器的名字和版本号不如确切知道它实用的是什么呈现引擎。目前只要检测五大呈现引擎即可:IE、Gecko、WebKit、KHTML 和 Opera。(为了不在全局作用域中添加多余的变量,我们将使用模块增强模式来封装检测脚本。)基本代码如下:
var client = function(){ var engine = { ie: 0, gecko: 0, webkit: 0, khtml: 0, opera: 0, ver: null //完整的版本 }; return { engine: engine };}();
做这样的区分可以支持像下面这样编写的代码:
if(client.engine.ie){ //针对 IE 的代码}else if (client.engine.gecko > 0){ if (client.engine.ver == "1.8.1"){ //针对这个版本执行某些操作 }}
检测顺序
关键是检测顺序要正确。由于用户代理字符串存在很多不一致的地方,如果检测顺序不对,很可能导致检测结果不正确。
第一步要识别 Opera:
if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}
第二步是 WebKit (检测字符串中的“AppleWebKit”):
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}
第三步是 KHTML:
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.khtml = parseFloat(engine.ver);}
第四步是 Gecko:
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.khtml = parseFloat(engine.ver);}else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){ engine.ver = RegExp["$1"]; engine.gecko = parseFloat(engine.ver);}
第五步是 IE:
var ua = navigator.userAgent;if (window.opera){ engine.ver = window.opera.version(); engine.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver);}else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.khtml = parseFloat(engine.ver);}else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){ engine.ver = RegExp["$1"]; engine.gecko = parseFloat(engine.ver);}else if (/MSIE ([^;]+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.ie = parseFloat(engine.ver);}
正则表达式
各正则表达式如下:
(useragentstring.com这里列出了各种浏览器的版本以及用户代理字符串。)
opera:
不需要正则表达式,使用window.opera.verson();
Webkit:
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
AppleWebKit\/(\S+) //AppleWebKit/537.36
KHTML:
Mozilla/5.0 (X11; Linux) KHTML/4.9.1 (like Gecko) Konqueror/4.9
Mozilla/5.0 (compatible; Konqueror/4.5; FreeBSD) KHTML/4.5.4 (like Gecko)
对于第一种:
KHTML\/(\S+) //KHTML/4.9.1Konqueror\/(\S+) //Konqueror/4.9
对于第二种:
KHTML\/(\S+) //KHTML/4.5.4Konqueror\/([^;]+) //Konqueror/4.5
Gecko:
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
rv:([^\)]+)\) Gecko\/\d{8} //rv:40.0) Gecko/20100101
IE:
Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0
对于第一种:
MSIE ([^,]+) //MSIE 11
对于第二种:
MSIE ([^;]+) //MSIE 10.6
识别浏览器
继续完善该代码:
var client = function(){ var engine = { ie: 0, gecko: 0, webkit: 0, khtml: 0, opera: 0, ver: null //完整的版本 }; var browser = {ie: 0, firefox: 0, safari: 0, konq: 0, opera: 0, chrome: 0, ver: null }; return { engine: engine };}();
由于大多数浏览器与其呈现引擎密切相关,所以下面示例中检测浏览器的代码与检测呈现引擎的代码是混合在一起的。
var ua = navigator.userAgent;if (window.opera){ engine.ver = browser.ver = window.opera.version(); engine.opera = browser.opera = parseFloat(engine.ver);}else if (/AppleWebKit\/(\S+)/.test(ua)){ engine.ver = RegExp["$1"]; engine.webkit = parseFloat(engine.ver); //确定是Chrome还是Safari if (/Chrome\/(\S+)/.test(ua)){ browser.ver = RegExp["$1"]; browser.chrome = parseInt(browser.ver); }else if(/Version\/(\S+)/.test(ua)){ browser.ver = RegExp["$1"]; browser.safari = parseInt(browser.ver); }else{ //近似的确定版本号 var safariVersion = 1; if (engine.webkit < 100){safariVersion = 1; }else if (engine.webkit < 312){safariVersion = 1.2; }else if (engine.webkit < 412){safariVersion = 1.3; }else {safariVersion = 2; } browser.safari = browser.ver = safariVersion; } }else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){ engine.ver = browser.ver = RegExp["$1"]; engine.khtml = browser.konq = parseFloat(engine.ver);}else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){ engine.ver = RegExp["$1"]; engine.gecko = parseFloat(engine.ver); //确定不是firefox if(/Firefox\/(\S+)/.test(ua)){ browser.ver = RegExp["$1"]; browser.firefox = parseFloat(browser.ver); }}else if (/MSIE ([^;]+)/.test(ua)){ engine.ver = browser.ver = RegExp["$1"]; engine.ie = browser.ie = parseFloat(engine.ver);}
识别平台
略
识别Windows操作系统
略
识别移动设备
略
识别游戏系统
略