关于浏览器类型和版本号的思考
很多时候,我们需要根据浏览器版本做这样或者那样的事情,这里主要包括JS层的和CSS样式层面上。
CSS层面上的话,这里我就不比多说了主要是因为浏览器对CSS样式标准支持的程度不一样导致的,最多见的就是IE系的;JS层面的话是浏览器在最初标准不统一是出现的各种问题,形成了当前的各种令人头疼的问题,即使是同一种浏览器在不同的版本号下可能也会存在各种的问题,这个时候处理浏览器的兼容性就至关重要了,那我们就需要能够分清楚用户当前使用的是什么样的浏览器,该做什么样的事情。这个的话可以多学习一下类似jquery、qwrap这样的JS库是怎么实现的,会有很大的裨益。
我遇到的一种情况是,在用户使用safari或者webview与safari同一内核的客户端,在访问我的页面时,走一个特殊的处理途径。我使用了UA判断时候包含safari字样这样的逻辑来判断是否走特殊逻辑,这个时候有一种情况,没有考虑到:在IOS系统上开发的APP,如QQ、微信,他们访问我的页面时并没有走特殊逻辑,这是什么原因呢?原来这些客户端的UA中并未包含safari字样,想想也是,他们并不是safari。我通过其他方式解决了这个问题,这里先卖个关子,下面会详细说明一下到底是怎么解决的。
我们知道,前端要想获取浏览器的类型和版本号,唯一途径就是通过JS获取浏览器或者客户端使用webview的useragent来进行判断。那么到底什么是useragent呢?
当您访问一个网页时,您的浏览器会给服务器发送用户代理字符串,这串显示您在什么浏览器以及浏览器的版本号,以及您系统的详细信息,如操作系统和版本号。这个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。以IE为例,它的代理格式如下所示:
如上图所示,UA的标准写法是:浏览器标识 (操作系统标识; 加密等级标识; 浏览器语言) 渲染引擎标识 版本信息。了解了这个之后,对于我们获取浏览器有很大帮助。
说了这么多,接下来就该我们的大神登场了。
navigator.userAgent //用户代理信息:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 navigator.appCodeName //浏览器代码名:Mozilla navigator.appName //浏览器的名称:Netscape navigator.appVersion //浏览器的平台和版本信息:5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
JS为我们提供了获取浏览器类型和版本号的方法,我们需要处理的就是navigator。userAgent。一般情况下我们会使用正则判断:
//这是Qwrap关于浏览器类型检测实现的方式 var na = window.navigator, ua = na.userAgent.toLowerCase(), browserTester = /(msie|webkit|gecko|presto|opera|safari|firefox|chrome|maxthon|android|ipad|iphone|webos|hpwos|trident)[ \/os]*([\d_.]+)/ig, Browser = { platform: na.platform }; ua.replace(browserTester, function(a, b, c) { if (!Browser[b]) { Browser[b] = c; } }); console.log(Browser) //Object {platform: "MacIntel", webkit: "537.36", chrome: "39.0.2171.95", safari: "537.36”}
例子中的UA是我使用浏览器的代理信息,已经检测输出的结果。在移动设备上存在一些差异,这里可以查询一些移动厂商生产的手机user-agent。
上面讲的是比较通用的一种做法,还有一种简单的最佳实践。他的原则就是针对特定功能使用正确的特性识别。比如下面的例子:针对IE或IE内核浏览器的的代码兼容性支持
// 单个浏览器识别: var isIE6 = navigator.userAgent.indexOf("MSIE 6.0") !== -1; var isIE7 = navigator.userAgent.indexOf("MSIE 7.0") !== -1; var isIE8 = navigator.userAgent.indexOf("MSIE 8.0") !== -1; var isIE9 = navigator.userAgent.indexOf("MSIE 9.0") !== -1; var isIE10 = navigator.userAgent.indexOf("MSIE 10.0") !== -1; //!var isIE11 = navigator.userAgent.indexOf("IE 11.0") !== -1; var isIE11 = /\btrident\/[0-9].*rv[ :]11\.0/.test(navigator.userAgent); // 多个浏览器识别 var isIE678 = /\bMSIE [678]\.0\b/.test(navigator.userAgent);
还有一种最佳实践的做法,可以根据页面的html注释来做判断。如:
<!DOCTYPE html> <!--[if lt IE 7]> <html class="ie6 oldie" lang=zh> <![endif]--><!--[if IE 7]> <html class="ie7 oldie" lang=zh> <![endif]--><!--[if IE 8]> <html class="ie8 oldie" lang=zh> <![endif]--><!--[if gt IE 8]><!—> <html><!--<![endif]—>
可以通过判断html包含的class,来判断当前浏览器渲染的是那种内核的浏览器。
我使用的是一个设备和浏览器判断的插件来做的,这个插件做的就是将各种浏览器和主要移动设备的UA进行正则判断,返回同一的数据格式,方便使用者进行组合使用。想要想些了解的可以移步github。在此,感谢detector作者分享这么好用的工具。
参考资料:
http://www.966266.com/jishu/ie-user-agent-jieshao.html
https://github.com/wedteam/qwrap/blob/master/resource/js/core/browser.js