zoukankan      html  css  js  c++  java
  • 用户代理检测与浏览器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
         + "
    浏览器版本:"+browserVer
         + "
    浏览器内核:"+useEngine
         + "
    内核版本:"+engineVer
         + "
    当前操作系统:"+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的知识,感觉略微过时了,想着自己整理一下

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

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

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

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

    .
    .
    查看大图

  • 相关阅读:
    Something I know about WebDynpro
    Details about support package implementation
    CRM Middleware Performance Topics
    Way to configure the logon navigaion layouts via Business Roles in CRM
    DOM 常用节点类型和方法
    第一届 xdef 会议日程
    去除百度音乐盒广告的chrome插件 持续更新
    从人人网抓取高校数据信息,包括,省份 高校 院系 (提供最终SQL文件下载)
    PHP 与 JSON
    解决HTTPS 发送请求走socket问题
  • 原文地址:https://www.cnblogs.com/hykun/p/Ua.html
Copyright © 2011-2022 走看看