用户代理检测与浏览器Ua详细分析

前言:用户代理字符串与用户代理检测

“用户代理字符串”(User Agent,下文简称“Ua”)是浏览器用来标识自身信息的一串字符

现如今,Ua一般包含有浏览器品牌、版本、内核、所在操作系统环境等信息

它也有着“悠久”而混乱的历史

若您对这段“黑历史”感兴趣

推荐阅读Hejin.Wong《用户代理字符串简史》一文,本文不再赘述

而“用户代理检测”则是通过检测Ua来确定实际使用的浏览器及其内核等信息

本文将从浏览器内核和浏览器本身的角度出发

通过亲测用户代理字符串,梳理各主流浏览器(本文仅限桌面端)内核、版本等信息

以及分享通过JavaScript进行用户代理检测的方法

注:本文代码基于[美]Nicholas C.ZakasJavaScript高级程序设计(第3版)》,并已根据现实情况进行优化

先看结论/可用代码

通过在JavaScript中引用以下代码

即可在需要的时候方便的测出用户所用浏览器的用户代理字符串、浏览器品牌、版本、内核等信息

var client=function(){

   var engine={    //呈现引擎
      trident:0,
      gecko:0,
      webkit:0,
      khtml:0,
      presto:0,
      ver:null     //具体的版本号
   };
   var browser={   //浏览器
      ie:0,
      firefox:0,
      safari:0,
      konq:0,
      opera:0,
      chrome:0,
      ver:null     //具体的版本号
   };
   var system={    //操作系统
      win:false,
      mac:false,
      x11:false
   };

   var ua=navigator.userAgent;
   if(/AppleWebKit\/(\S+)/.test(ua)){        //匹配Webkit内核浏览器(Chrome、Safari、新Opera)
      engine.ver=RegExp["$1"];
      engine.webkit=parseFloat(engine.ver);
      if(/OPR\/(\S+)/.test(ua)){             //确定是不是引用了Webkit内核的Opera
         browser.ver=RegExp["$1"];
         browser.opera=parseFloat(browser.ver);
      }else if(/Chrome\/(\S+)/.test(ua)){    //确定是不是Chrome
         browser.ver=RegExp["$1"];
         browser.chrome=parseFloat(browser.ver);
      }else if(/Version\/(\S+)/.test(ua)){   //确定是不是高版本(3+)的Safari
         browser.ver=RegExp["$1"];
         browser.safari=parseFloat(browser.ver);
      }else{                                 //近似地确定低版本Safafi版本号
         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(window.opera){                 //只匹配拥有Presto内核的老版本Opera 5+(12.15-)
      engine.ver=browser.ver=window.opera.version();
      engine.presto=browser.opera=parseFloat(engine.ver);
   }else if(/Opera[\/\s](\S+)/.test(ua)){  //匹配不支持window.opera的Opera 5-或伪装的Opera
      engine.ver=browser.ver=RegExp["$1"];
      engine.presto=browser.opera=parseFloat(engine.ver);
   }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)){ //判断是不是基于Gecko内核
      engine.ver=RegExp["$1"];
      engine.gecko=parseFloat(engine.ver);
      if(/Firefox\/(\S+)/.test(ua)){                //确定是不是Firefox
         browser.ver=RegExp["$1"];
         browser.firefox=parseFloat(browser.ver);
      }
   }else if(/Trident\/([\d\.]+)/.test(ua)){         //确定是否是Trident内核的浏览器(IE8+)
      engine.ver=RegExp["$1"];
      engine.trident=parseFloat(engine.ver);
      if(/rv\:([\d\.]+)/.test(ua)||/MSIE ([^;]+)/.test(ua)){   //匹配IE8-11+
         browser.ver=RegExp["$1"];
         browser.ie=parseFloat(browser.ver);
      }
   }else if(/MSIE ([^;]+)/.test(ua)){               //匹配IE6、IE7
      browser.ver=RegExp["$1"];
      browser.ie=parseFloat(browser.ver);
      engine.ver=browser.ie-4.0;                    //模拟IE6、IE7中的Trident值
      engine.trident=parseFloat(engine.ver);
   }

   var p=navigator.platform;                        //判断操作系统
   system.win=p.indexOf("Win")==0;
   system.mac=p.indexOf("Mac")==0;
   system.x11=(p.indexOf("X11")==0)||(p.indexOf("Linux")==0);
   if(system.win){
      if(/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){
         if(RegExp["$1"]=="NT"){
            system.win = ({
               "5.0" : "2000",
               "5.1" : "XP",
               "6.0" : "Vista",
               "6.1" : "7",
               "6.2" : "8",
               "6.3" : "8.1",
               "10" : "10"
            })[RegExp["$2"]] || "NT";
         }else if(RegExp["$1"]=="9x"){
            system.win="ME";
         }else{
            system.win=RegExp["$1"];
         }
      }
   }

   return {
      ua:ua,          //用户浏览器Ua原文
      engine:engine,  //包含着用户浏览器引擎(内核)信息
      browser:browser,//包括用户浏览器品牌与版本信息
      system:system   //用户所用操作系统及版本信息
   };

}();

[2015/01/16注:以上代码测试并吸收了本文评论中@luobotang的建议,感谢反馈]

以上代码封装了一个命名为client的函数对象

实际开发中,引用了上述代码后,可以如下面示例代码所示,灵活运用client对象中的信息

if(client.engine.webkit){ //如果是基于Webkit内核的浏览器
   if(client.browser.chrome){    //若是Google Chrome浏览器
      //执行针对Chrome的代码
   } else if {client.browser.safari}{
      //执行针对Safari的代码
   }
} else if (client.engine.gecko){ //若是基于Cecko内核的浏览器
   if(client.browser.firefox){
      //执行针对Firefox的代码
   } else {
      //执行针对其他基于Gecko内核的浏览器的代码
   }
}

下文将会使用以下代码alertUa等信息作为测试参考并提供截图(点击截图可放大查看)

若您需要亲测任何浏览器的信息,可将以下代码粘贴于上文第一段代码(client对象)后并在浏览器中运行

alert(client.ua);

var browserName="";             //保存当前使用的浏览器品牌信息
var browserVer=0;               //保存当前使用的浏览器版本信息
for(var i in client.browser){
   if(client.browser[i]){
      browserName=i;
      browserVer=client.browser[i];
      break;
   }
}

var useEngine="";               //保存当前浏览器引擎(内核)名称
var engineVer=0;                //保存当前使用的浏览器引擎版本
for(var i in client.engine){
   if(client.engine[i]){
      useEngine=i;
      engineVer=client.engine[i];
      break;
   }
}

var useSystem="";               //保存当前操作系统信息
for(var i in client.system){
   if(client.system[i]){
      i== "win"?useSystem = "Windows "+client.system[i]:useSystem=i;
      break;
   }
}

alert( "当前使用的浏览器:"+browserName
     + "\n浏览器版本:"+browserVer
     + "\n浏览器内核:"+useEngine
     + "\n内核版本:"+engineVer
     + "\n当前操作系统:"+useSystem);

浏览器市场份额现状

首先通过数据了解一下目前浏览器市场份额现状

根据“百度统计|流量研究院”的数据

下图/表是2014年全年国内浏览器市场份额情况

浏览器名称市场份额
.Internet Explorer 50.03%
.Google Chrome 27.73%
.搜狗高速浏览器 4.77%
.猎豹浏览器 2.46%
.QQ浏览器 2.19%
.2345浏览器 1.67%
.其它 11.15%

由此可以看出,在国内,IE浏览器占据了“大半江山”

紧随其后的是Google Chrome浏览器

排在第3456位的均是国产壳浏览器

再看一下2014年11月全球浏览器市场份额情况(数据来自“浏览迷”)

浏览器名称市场份额
.Internet Explorer 58.94%
.Google Chrome 20.57%
.Firefox 13.26%
.Safari 5.9%
.Opera 0.88%
.其它 0.45%

从全世界的范围上看,IE浏览器的市场份额更加可观,达到近6

这些数据对于分析浏览器内核、生产兼容性强的前端项目具有重要的参考意义

Mozilla Firefox

Mozilla Firefox(火狐)是我个人最为崇敬的浏览器品牌

相比较而言,火狐浏览器性能优越、坚持标准、勇于尝试(......好了,真心的,这可不是植入广告)

它更拥有独立的呈现引擎(内核)Gecko /ˈgekəʊ/

以下是我亲测整理的火狐浏览器各主要版本Ua及通过Ua解析出的信息(点击缩略图可放大查看)

Mozilla Firefox 1.0
firefox1Uafirefox1
Mozilla/5.0 (Windows: U; Windows NT 5.1; zh-CN; rv:1.7.5) Gecko/20041124 Firefox/1.0
Mozilla Firefox 3.6
firefox3.6Uafirefox3.6
Mozilla/5.0 (Windows: U; Windows NT 6.0; zh-CN; rv:1.9.2.18) Gecko/20110614 Firefox/3.6.18
Mozilla Firefox 8.0
firefox8Uafirefox8
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0.1) Gecko/20100101 Firefox/8.0.1
Mozilla Firefox 36
firefox36Uafirefox36
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0

通过如上亲测和书本介绍可知,火狐浏览器的Ua具有如下特征

  1. 相对稳定,从第一个版本至今变化不大;
  2. 有正确标识版本、内核、所在操作系统等基本信息;
  3. 一直是以“Mozilla 5.0”开头,今后估计也不会变化;
  4. Firefox 4后,“Gecko版本号”固定为“Gecko/20100101”,基本失去作用;
  5. 末尾“Firefox/”后内容为浏览器真实版本号;
  6. rv:”后内容为Gecko内核版本号;
  7. 高版本的Firefox浏览器“Gecko”内核版本号与浏览器版本号相同。

从用户代理检测的难度上说,得益于火狐浏览器一直坚持规矩

分析起来是最简单的

运用如下JavaScript代码,配合正则表达式

即可轻松的将火狐浏览器的相关信息赋给相应对象

/*以下代码作用为判断与分析火狐浏览器Ua信息*/
//...
else if(/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){  //判断是不是基于Gecko内核
   engine.ver=RegExp["$1"];
   engine.gecko=parseFloat(engine.ver);
   if(/Firefox\/(\S+)/.test(ua)){                //确定是不是Firefox
      browser.ver=RegExp["$1"];
      browser.firefox=parseFloat(browser.ver);
   }
}
//...

具体代码本文第二部分“先看结论/可用代码”已详细给出,下同

Microsoft Internet Explorer

大名鼎鼎的IE浏览器可能也是一众前端程序员的噩梦

虽然它版本迭代缓慢、Bug频出、还有各种“怪癖”特性

但它倚仗Windows操作系统的垄断地位,无论全球还是国内,从市场占有率上看一直是老大

IE浏览器也有自己的内核Trident /ˈtraɪdnt/

同样根据“百度统计|流量研究院”的数据,看一下2014年国内浏览器按版本区分的市场份额占比情况

浏览器版本市场份额
.IE8 32.04%
.Google Chrome 27.73%
.IE6 7.37%
.IE9 7.14%
.搜狗高速浏览器 4.77%
.IE7 3.48%
.猎豹浏览器 2.46%
.QQ浏览器 2.19%
.2345浏览器 1.67%
.其它 11.15%

什么?IE10IE11居然还没排上号?

从数据上看,确实如此,老版本的IE(6/7/8/9)寿命是相当的长

这迫使前端开发必须考虑旧版本IE浏览器并为它的各个版本逐一DeBug和适配

下面通过亲测,比较一下各版本IE浏览器Ua的差异

Internet Explorer 6
IE6UaIE6
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Internet Explorer 7
IE7UaIE7
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1)
Internet Explorer 8
IE8UaIE8
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
Internet Explorer 9
IE9UaIE9
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; WOW64; Trident/5.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.30729)
Internet Explorer 10
IE10UaIE10
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
Internet Explorer 11
IE11UaIE11
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko

虽然稍显凌乱,但观察一下就能发现,IE6-10均有通过“MSIE”字段正确标识出当前IE版本

IE11(和接下来可能的IE12、13...)的Ua简直乱入啊

目的很明显,IE11试图将自己伪装成Gecko内核的浏览器(比如火狐),欺骗嗅探代码

这继续刷新着Ua本来就混乱的历史,真是惹人嫌......

通过如上亲测和书本介绍可知,IE浏览器的Ua具有如下特征

  1. IE6-10通过“MSIE”字段正确地标识自身版本信息;
  2. IE11通过“rv”字段标识自身版本信息;
  3. IE8及之后的版本添加了呈现引擎(Trident)的版本号,且Trident版本号都是IE版本号减4
  4. 有正确标识所在操作系统信息;
  5. IE11含有迷惑性字段“like Gecko”。

新增的Trident记号是为了让开发人员知道IE是不是在兼容模式下运行

如下例所示,若是运行在兼容模式下的IE8,则“MSIE”版本号会变成7,但Trident及其版本号还会留在Ua

运行在兼容模式下的IE8
IE8dUaIE8d
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)

综上比较,可以通过如下代码进行针对IE的用户代理检测

/*以下代码作用为判断与分析IE浏览器Ua信息*/
//...
else if(/Trident\/([\d\.]+)/.test(ua)){          //确定是否是Trident内核的浏览器(IE8+)
   engine.ver=RegExp["$1"];
   engine.trident=parseFloat(engine.ver);
   if(/rv\:([\d\.]+)/.test(ua)||/MSIE ([^;]+)/.test(ua)){   //匹配IE8-11+
      browser.ver=RegExp["$1"];
      browser.ie=parseFloat(browser.ver);
   }
}else if(/MSIE ([^;]+)/.test(ua)){               //匹配IE6、IE7
   browser.ver=RegExp["$1"];
   browser.ie=parseFloat(browser.ver);
   engine.ver=browser.ie-4.0;                    //模拟IE6、IE7中的Trident值
   engine.trident=parseFloat(engine.ver);
}
//...

值得注意的是,以上代码会根据“Trident内核版本号=IE版本号-4”的规律

IE6的“Trident”内核版本标记为“2.0”,将IE7的“Trident”内核版本标记为“3.0”,以此统一“Trident”标记

Google Chrome

从市场份额上看,无论是世界范围内还是国内,PCGoogle Chrome都是仅次于IE的浏览器

不过这可能也与大多数国产套壳浏览器均使用ChromeWebKit内核有关

先看一下Google Chrome各主要版本Ua情况

Google Chrome 1
chrome1Uachrome1
Mozilla/5.0 (Windows: U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.48 Safari/525.19
Google Chrome 10
chrome10Uachrome10
Mozilla/5.0 (Windows: U; Windows NT 6.0; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
Google Chrome 27
chrome27Uachrome27
Mozilla/5.0 (Windows: U; Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Google Chrome 39
chrome39Uachrome39
Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36

通过如上亲测和书本介绍可知,Chrome浏览器的Ua具有如下特征

  1. 使用“AppleWebKit”字段正确标识所用内核为“WebKit”及其版本号;
  2. Chrome/”及其后数值正确标识了浏览器品牌及版本信息;
  3. 一直是以“Mozilla 5.0”开头,今后估计也不会变化;
  4. 有正确标识所在操作系统信息;
  5. 均含有迷惑性字段“(KHTML, like Gecko)”;
  6. 末尾“Safari/”字段视图将自己伪装成SafariWebKit版本与Safari版本看起来似乎始终保持一致。

Chrome使用的呈现引擎(内核)是WebKit

但是,在Chrome 28之后,谷歌宣布将使用Blink引擎

不过Blink引擎也是基于WebKit的,关于更改引擎的变化,截至目前仍然没有在Ua中表现出来

综上,可以使用如下JavaScript代码配合正则表达式进行针对Chrome浏览器的用户代理检测

/*以下代码作用为判断与分析Chrome浏览器Ua信息*/
if(/AppleWebKit\/(\S+)/.test(ua)){        //匹配Webkit内核浏览器(Chrome、Safari、新Opera)
   engine.ver=RegExp["$1"];
   engine.webkit=parseFloat(engine.ver);
   if(/OPR\/(\S+)/.test(ua)){             //确定是不是引用了Webkit内核的Opera
      //...
   }else if(/Chrome\/(\S+)/.test(ua)){    //确定是不是Chrome
      browser.ver=RegExp["$1"];
      browser.chrome=parseFloat(browser.ver);
   }else if(/Version\/(\S+)/.test(ua)){   //确定是不是高版本(3+)的Safari
      //...
   }
//...

Apple Safari

苹果Safari浏览器作为Mac OS系统的官方浏览器,自然也有可观的用户数

该浏览器也是基于WebKit内核

因为楼主还是大学生一枚,暂时买不起MacBook,安装黑苹果的过程又让我累觉不爱......

所以关于SafariUa没能测试得如其它浏览器般详细

根据书本介绍,Safari 3.0之前的Ua类似如下所示

Mozilla/5.0 (Macintosh; U; PPC Mac OS X;en) AppleWebKit/124 (KHTML, like Gecko) Safari/125.1

用了自己的电脑安装了个Safari for Windows,借了同学一个MacBook做了如下亲测

Apple Safari 5.1
safari5.1Uasafari5.1
Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/534.57.2 (KHTML,like Gecko) Version/5.1.7 Safari/534.57.2
Apple Safari 6
safari6Uasafari6
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1

根据书本介绍和如上亲测,Safari浏览器的Ua具有如下特征

  1. 使用“AppleWebKit”字段正确标识所用内核为“WebKit”及其版本号;
  2. Safari”标识了浏览器品牌信息;
    (并不像Chrome浏览器一样即包含“Chrome”字段又包含迷惑性“Safari”字段)
  3. Safari 3.0以上版本通过“Version字段正确标识浏览器版本信息(这只在Safari中存在);
  4. 一直是以“Mozilla 5.0”开头,今后估计也不会变化;
  5. 有正确标识所在操作系统信息;
  6. 均含有迷惑性字段“(KHTML, like Gecko)”;

综上,使用如下代码配合正则表达式可以进行针对Safari浏览器的用户代理检测

/*以下代码作用为判断与分析Safari浏览器Ua信息*/
if(/AppleWebKit\/(\S+)/.test(ua)){        //匹配Webkit内核浏览器(Chrome、Safari、新Opera)
   engine.ver=RegExp["$1"];
   engine.webkit=parseFloat(engine.ver);
   //...
   }else if(/Version\/(\S+)/.test(ua)){   //确定是不是高版本(3+)的Safari
      browser.ver=RegExp["$1"];
      browser.safari=parseFloat(browser.ver);
   }else{                                 //近似地确定低版本Safafi版本号
      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;
   }
//...

其中,因为低版本Safari 2-不包含标识浏览器版本号的“version”属性(不过如今低版本Safari用户数应该极少了)

故只能使用一些if语句做近似判断

Opera

Opera(欧朋)浏览器也算得上是浏览器界的一朵奇葩了

Opera 12.16之前,它有着自己的内核Presto /'prestəʊ/

而之后,Opera改用Google ChromeBlink内核(同样基于WebKit

几近沦为一款套壳浏览器

虽然根据上文数据,Opera浏览器在国内的市场份额几乎可以忽略不计(被归入了“其它”范畴)

但据说其在欧洲市场还是有相当的人气,而且有着不同寻常的过去(自有内核)

所以本文还是将Opera单独分析

Opera 9.6
opera9.6Uaopera9.6
Opera/9.64 (Windows NT 6.0; U; Edition IBIS; zh-cn) Presto/2.1.1
Opera 12.15
opera12Uaopera12
Opera/9.80 (Windows NT 6.1; Win64; x64) Presto/2.12.388 Version/12.15
Opera 26
opera26Uaopera26
Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60

从以上测试和书本介绍可以知道,在Opera 9之前,其默认的用户代理字符串是所有现代浏览器中最合理的

没有任何伪装,且正确地标识了自身及其版本号

可是,因为因特网上不少浏览器嗅探代码只钟情于报告Mozilla产品名的那些Ua或只对IEGecko感兴趣

Opera没有伪装的Ua可能令某些站点的兼容性出现问题

于是,Opera就开始变奇葩了......

Opera 9以后,出现了两种修改用户代理字符串的方式

第一种方式是,针对某些站点,将自身表示为另外一个浏览器,只不过在末尾追加Opera品牌和版本信息,如下为例

Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50

第二种方式是,针对某些站点,直接隐瞒身份,Ua与其它浏览器返回的相同

注意,这些奇葩行为都是针对某些站点的,这令用户代理检测识别Opera难上加难

不过,通过以上亲测,还是可以总结出正常情况下OperaUa的一些特点

  1. Opera 9.8之前,Ua开头的“Opera/”字段正确标识出了浏览器品牌和版本信息;
  2. Opera 9.8-12.15中,Ua开头固定为“Opera/9.8,但有通过“Version”字段正确标识版本信息;
  3. Opera 12.15之前,一直有通过Presto字段正确地标识Presto内核及其版本信息;
  4. Opera 12.16后,因为使用了Blink(WebKit)内核,
    出现“AppleWebKit”字段正确标识内核及内核版本信息,
    同时出现“Chrome”、“Safari”、“(KHTML, like Gecko)”伪装字段;
  5. 使用了Blink(Webkit)内核后,Ua末尾通过“OPR”字段标识浏览器品牌及版本信息;
  6. 一直有正确标识所在操作系统信息。

此外,Opera 5+独家支持通过window.opera探测浏览器版本等信息

尽管无法通过用户代理检测获得隐瞒身份状态下的Opera信息

但还是可以根据以上规律,使用以下代码检测正常情况下OperaUa信息

/*以下代码作用为判断与分析Opera浏览器Ua信息*/
if(/AppleWebKit\/(\S+)/.test(ua)){      //匹配Webkit内核浏览器(Chrome、Safari、新Opera)
   engine.ver=RegExp["$1"];
   engine.webkit=parseFloat(engine.ver);
   //...
}else if(window.opera){                 //只匹配拥有Presto内核的老版本Opera 5+(12.15-)
   engine.ver=browser.ver=window.opera.version();
   engine.presto=browser.opera=parseFloat(engine.ver);
}else if(/Opera[\/\s](\S+)/.test(ua)){  //匹配不支持window.opera的Opera 5-或伪装的Opera
   engine.ver=browser.ver=RegExp["$1"];
   engine.presto=browser.opera=parseFloat(engine.ver);
}
//...

呈现引擎(浏览器内核)

上文从浏览器的角度出发,分析了几大世界知名浏览器的Ua

下面就从浏览器内核的角度,做一个简单地整理

内核浏览器
Webkit Google Chrome (Blink)
Apple Safari
Opera 12.16+ (Blink)
Trident Microsoft Internet Explorer
Gecko Mozilla Firefox
Presto Opera 12.15-

国产浏览器

国产浏览器全部都是套壳浏览器,都离不开上述内核

因为在国内,国产浏览器用户数庞大,开发前端项目的过程中也不得不考虑国产浏览器所用的内核情况

下面将通过测试分析各主流国产浏览器Ua及内核情况(点击缩略图可放大查看)

QQ浏览器 qqBrowserUa Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; QQBrowser/8.0.2959.400; rv:11.0) like Gecko Trident
(调用系统IE内核)
百度浏览器 baiduBrowserUa Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/38.0.2125.122 BIDUBrowser/7.0 Safari/537.36 Blink
(WebKit)
UC浏览器 ucBrowserUa1 Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36 高速模式内核
WebKit
ucBrowserUa2 Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML, like Gecko UBrowser/4.0.3214.0) Chrome/36.0.1985.143 Safari/537.36 Edge/12.0 兼容模式内核
Trident
(调用系统IE内核)
搜狗高速浏览器 sougouBrowserUa Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0 WebKit
猎豹安全浏览器 liebaoBrowserUa Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36 LBBROWSER WebKit
360安全浏览器 360BrowserUa1 Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 高速模式内核
WebKit
360BrowserUa2 Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko 兼容模式内核
Trident
(调用系统IE内核)
360极速浏览器 360BrowserUa3 Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 Blink
(WebKit)
2345王牌浏览器 2345BrowserUa1 Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko 高速模式内核
Trident
2345BrowserUa2 Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko 兼容模式内核
Trident
(调用系统IE内核)
2345加速浏览器 2345BrowserUa3 Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/31.0.1650.69 Safari/537.36 2345chrome v2.5.0.3895 WebKit

通过以上测试实践,可以得出一些关于国产浏览器内核及Ua的结论

  1. 国产浏览器内核不是WebKit就是Trident(调用系统IE内核);
  2. 使用WebKit内核的国产浏览器最新版本的内核基本能保持接近Chrome最新版本内核;
  3. 部分国产浏览器没有在Ua中标注自身信息
    使得开发者难以通过用户代理检测判断用户使用的国产浏览器类型

若使用上文中的代码检测国产浏览器品牌,则不是返回Chrome就是返回IE

这是因为只有一部分国产浏览器有在Ua中正确标注自身信息,难以准确检测

不过其实也基本没必要检测到国产浏览器具体品牌,检测其是什么内核比品牌重要吧

感慨一下,国产浏览器什么时候才能拥有自己的内核啊......

判断操作系统

在本文“先看结论/可用代码”部分中,还有一部分代码是用于检测Ua中包含的操作系统信息

根据常识,我们知道当前流行的操作系统有Windows XP/Vista/7/8/8.1/10Mac OSUnix

可以通过类似以下代码检测用户当前使用的操作系统

/*以下代码作用为检测用户当前使用的操作系统平台*/
//...
var p=navigator.platform;   //判断操作系统
system.win=p.indexOf("Win")==0;
system.mac=p.indexOf("Mac")==0;
system.x11=(p.indexOf("X11")==0)||(p.indexOf("Linux")==0);
//...

之所以是使用navigator.platform是因为这样要比检测用户代理字符串更加简单

navigator.platform属性可能的值包括“Win32”、“Win64”、“MacPPC”、“MacIntel”、“X11”和"Linux i686"等

还好这些值在不同浏览器中都是一致的,使得检测平台变得简单

若用户使用的是Windows平台,还可以通过Ua检测其版本

需要注意的是,在Ua中,Windows的版本并不直观,用来表示版本的数字其实是当前Windows内核版本

当前主流Windows版本及其内核对照表如下

版本内核版本
Windows XP 5.1
Windows Vista 6.0
Windows 7 6.1
Windows 8 6.2
Windows 8.1 6.3
Windows 10 技术预览版 6.4
Windows 10 (Build 9880+) 10

故可以通过类似以下代码检测用户所在Windows平台的版本

/*以下代码作用为检测用户使用的Windows版本*/
if(system.win){
      if(/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){
         if(RegExp["$1"]=="NT"){
            system.win = ({
               "5.0" : "2000",
               "5.1" : "XP",
               "6.0" : "Vista",
               "6.1" : "7",
               "6.2" : "8",
               "6.3" : "8.1",
               "10" : "10"
            })[RegExp["$2"]] || "NT";
         }else if(RegExp["$1"]=="9x"){
            system.win="ME";
         }else{
            system.win=RegExp["$1"];
         }
      }
   }

[2015/01/16注:以上代码测试并吸收了本文评论中@luobotang的建议,感谢反馈]

检测用户操作系统应该是统计作用大于功能作用吧!

随笔感想

本文略长,不知有没有人看到这里了呢?

看书本介绍关于Ua的知识,感觉略微过时了,想着自己整理一下

虚拟机搞呀搞,也没想到倒饬了这么久才搞定,具体是做了几天自己都忘了,此外排版综合症又发作了......

其实也不知道做这件事情有没有意义,只是喜欢就做做

不过强调一下,楼主只是大学菜鸟一只,本文所整理的内容虽多为实践,但也可能有纰漏

若路过的大牛发现本文有什么问题,欢迎您不吝留言指正哦!我会及时修改的!

.
.
查看大图

posted @ 2014-12-28 18:53 黄映焜 阅读(...) 评论(...) 编辑 收藏