• 用户代理检测与浏览器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的知识,感觉略微过时了,想着自己整理一下

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

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

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

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

    .
    .
    查看大图

  • 相关阅读:
    ckeditor 3.0.1使用
    也谈QQ表情弹出框的制作
    百度的模态弹出窗口
    day03 set集合,文件操作,字符编码以及函数式编程
    写在开始之前
    day07 类的进阶,socket编程初识
    day06 面向对象编程
    day02 Python 的模块,运算,数据类型以及方法
    day04 装饰器 迭代器&生成器 Json & pickle 数据序列化 内置函数
    day08 多线程socket 编程,tcp粘包处理
  • 原文地址:https://www.cnblogs.com/hykun/p/Ua.html
Copyright © 2020-2023  润新知