资讯专栏INFORMATION COLUMN

《JavaScript高级程序设计》笔记:客户端检测(九)

aaron / 1026人阅读

摘要:由于怪癖检测无法精确地检测特定的浏览器和版本。用户代理检测需要特殊的技巧,特别是要注意会隐瞒其用户代理字符串的情况。而在客户端,用户代理检测一般被当作一种万不得已的做法,其优先级排在能力检测和怪癖检测之后。

能力检测

在编写代码之前先检测特定浏览器的能力。例如,脚本在调用某个函数之前,可能要先检测该函数首付存在。这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意力集中到相应的能力是否存在上。能力检测无法精确地检测特定的浏览器和版本。

怪癖检测

怪癖实际上是浏览器实现中存在的bug,例如早期的webkit中就存在一个怪癖,即它会再for-in循环中返回被隐藏的属性。怪癖检测通常涉及到运行一段代码,然后确定浏览器是否存在某个怪癖。由于怪癖检测无法精确地检测特定的浏览器和版本。

用户代理检测

通过检测用户代理字符串来识别浏览器。用户代理字符串中包含大量与浏览器有关的信息,包括浏览器、平台、操作系统及浏览器版本。用户代理字符串有过一段相当长的发展历史,在此期间,浏览器提供商视图通过在用户代理字符串总添加一些欺骗性信息,欺骗网站详细自己的浏览器是另外一种浏览器。用户代理检测需要特殊的技巧,特别是要注意Opera会隐瞒其用户代理字符串的情况。即便如此,通过用户代理字符串仍然能够检测出浏览器所用的呈现引擎以及所在的平台,包括移动设备和游戏系统。

在每一次HTTP请求过程中,用户代理字符串是作为响应首部发送的,而且该字符串可以通过Javascript的navigator.userAgent属性访问。在服务器端,通过检测用户代理字符串来确定用户使用的浏览器是一种常用而且广为接受的做法。而在客户端,用户代理检测一般被当作一种万不得已的做法,其优先级排在能力检测和怪癖检测之后。

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
    };

    // 检测呈现引擎和浏览器
    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 = parseFloat(engine.ver);
        } else if (/Version/(S+)/.test(ua)) {
            browser.ver = RegExp["$1"];
            browser.safari = parseFloat(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.kong = 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);

    }

    // 检测浏览器
    browser.ie = engine.ie;
    browser.opera = engine.opera;

    // 返回这些对象
    return {
        engine:engine,
        browser: browser
    }
}();

console.log(client.engine);
console.log(client.browser);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85403.html

相关文章

  • ApacheCN 人工智能知识树 v1.0

    摘要:贡献者飞龙版本最近总是有人问我,把这些资料看完一遍要用多长时间,如果你一本书一本书看的话,的确要用很长时间。为了方便大家,我就把每本书的章节拆开,再按照知识点合并,手动整理了这个知识树。 Special Sponsors showImg(https://segmentfault.com/img/remote/1460000018907426?w=1760&h=200); 贡献者:飞龙版...

    刘厚水 评论0 收藏0
  • JavaScript高级程序设计笔记:BOM(八)

    摘要:浏览器对象模型提供了很多对象,用于访问浏览器的功能,这些功能与任何网页内容无关。对象基本上只用来表明客户端的能力。 BOM(浏览器对象模型)提供了很多对象,用于访问浏览器的功能,这些功能与任何网页内容无关。 window对象 全局作用域 定义全局变量与在window对象上直接定义属性还是有一点差别:全局变量不能通过delete操作符删除,而直接在window对象上的定义的属性可以。 v...

    mushang 评论0 收藏0
  • SegmentFault 技术周刊 Vol.30 - 学习 Python 来做一些神奇好玩的事情吧

    摘要:学习笔记七数学形态学关注的是图像中的形状,它提供了一些方法用于检测形状和改变形状。学习笔记十一尺度不变特征变换,简称是图像局部特征提取的现代方法基于区域图像块的分析。本文的目的是简明扼要地说明的编码机制,并给出一些建议。 showImg(https://segmentfault.com/img/bVRJbz?w=900&h=385); 前言 开始之前,我们先来看这样一个提问: pyth...

    lifesimple 评论0 收藏0
  • javascript高级程序设计笔记检测数组的方法

    摘要:如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。 如何检测某个变量是否为数组? 《javascript 高级程序设计》原文摘录: 自从 ECMAScript 3 做出规定以后,就出现了确定某个对象是不是数组的经典问题...

    wums 评论0 收藏0

发表评论

0条评论

aaron

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<