资讯专栏INFORMATION COLUMN

客户端检测之用户代理检测 — navigator.userAgent

MangoGoing / 1918人阅读

摘要:检测脚本的基本代码结构如下所示呈现引擎具体的版本号检测呈现引擎全局变量,用于保存相关信息。如果检测到了哪个呈现引擎,那么就以浮点数值形式将该引擎的版本号写入相应的属性。

前言

前端这东西,各种先有事实后有标准。不管是各大浏览器老哥各自为政,还是w3c姗姗来迟,既有事实标准难以更改。虽说多方割据,互相竞争,总比一家独大,爱更不更来得好。但却苦了我们这些平头小码农?,颈椎病又加深了啊。
之前阅读了《JavaScript高级程序设计》,今日准备将其用户代理检测源码部分做个归纳。
槽不多吐,开始正文!
博文地址:客户端检测之用户代理检测 — navigator.userAgent

1.客户端检测

面对各浏览器普遍存在的不一致性问题,开发人员就得利用各种客户端检测方法,来突破或规避各种局限性。
检测Web客户端的手段很多,各有利弊。在服务器端,用户代理检测是一种常用且广为接收的做法。通过对浏览器发送的用户代理字符串的内容进行检测,来识别用户的浏览器。

2.navigator.userAgent

BOM,即浏览器对象模型。BOM提供了很多对象,用于访问浏览器的功能,且这些功能与网内内容无关。其主要方面已被w3c加入HTML5豪华套餐。
BOM包含windowlocationnavigatorscreenhistory对象,navigator对象中的userAgent属性便是用户代理字符串

3.用户代理检测代码
var ua = navigator.userAgent;//用户代理字符串
3.1 呈现引擎检测

主要检测五大呈现引擎(渲染引擎):IE、Gecko、WebKit、KHTML 和 Opera。
为了不在全局作用域中添加多余的变量,使用模块增强模式来封装检测脚本。检测脚本的基本代码结构如下所示:

var client = function () {
    var engine = {
        //呈现引擎
        ie: 0,
        gecko: 0,
        webkit: 0,
        khtml: 0,
        opera: 0,
        //具体的版本号
        ver: null
    };
    //检测呈现引擎

    return {
        engine: engine
    };
}();

client全局变量,用于保存相关信息。匿名函数内部定义了一个局部变量engine,每个呈现引擎都对应着一个属性,属性的值默认为0。如果检测到了哪个呈现引擎,那么就以浮点数值形式将该引擎的版本号写入相应的属性。而呈现引擎的完整版本(是一个字符串),则写入ver属性。

//检测呈现引擎
var ua = navigator.userAgent;
if (window.opera) {
        engine.ver = window.opera.version();
        engine.opera = parseFloat(engine.ver);
    } else if (/AppleWebKit/(S+)/.test(ua)) {
        engine.ver = RegExp["$1"];
        engine.webkit = parseFloat(engine.ver);
    } else if (/KHTML/(S+)/.test(ua)) {
        engine.ver = RegExp["$1"];
        engine.khtml = parseFloat(engine.ver);
    } else if (/rv:([^)]+)) Gecko/d{8}/.test(ua)) {
        engine.ver = RegExp["$1"];
        engine.gecko = parseFloat(engine.ver);
    } else if (/MSIE ([^;]+)/.test(ua)) {
        engine.ver = RegExp["$1"];
        engine.ie = parseFloat(engine.ver);
    }
3.2 识别浏览器
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
    };
    //检测呈现引擎和浏览器

    return {
        engine: engine,
        browser: browser
    };
}();

代码中又添加了私有变量browser ,用于保存每个主要浏览器的属性。与engine变量一样,除了当前使用的浏览器,其他属性的值将保持为0;如果是当前使用的浏览器,则这个属性中保存的是浮点数值形式的版本号。同样,ver属性中在必要时将会包含字符串形式的浏览器完整版本号。
由于大多数浏览器与其呈现引擎密切相关,所以下面示例中检测浏览器的代码与检测呈现引擎的代码是混合在一起的。

//检测呈现引擎及浏览器
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(browser.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.konq = 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);
}
3.3 识别系统平台

很多时候,只要知道呈现引擎就足以编写出适当的代码了。但在某些条件下,平台可能是必须关注的问题。那些具有各种平台版本的浏览器(如 Safari、Firefox 和 Opera),在不同的平台下可能会有不同的问题。目前的三大主流平台是 Windows、Mac 和 Unix(包括各种 Linux)。
再添加一个新对象:

var client = function () {
    var system = {
        win: false,
        mac: false,
        x11: false
    };
    //检测设备
    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);
    return {
        engine: engine,
        browser: browser,
        system: system
    };
}();
3.3.1 识别具体Windows系统

Windows平台下,还可以从用户代理字符串中进一步取得具体的操作系统信息。下表列出了不同浏览器在表示不同的Windows操作系统时给出的不同字符串:

由于用户代理字符串中的Windows操作系统版本表示方法各异,因此检测代码并不十分直观。好在,从 Windows 2000 开始,表示操作系统的字符串大部分都还相同,只有版本号有变化。为了检测不同的Windows操作系统,必须要使用正则表达式。由于使用 Opera 7 之前版本的用户已经不多了,因此我们可以忽略这部分浏览器。

if (system.win) {
    if (/Win(?:dows )?([^do]{2})s?(d+.d+)?/.test(ua)) {
        if (RegExp["$1"] == "NT") {
            switch (RegExp["$2"]) {
                case "5.0":
                    system.win = "2000";
                    break;
                case "5.1":
                    system.win = "XP";
                    break;
                case "6.0":
                    system.win = "Vista";
                    break;
                case "6.1":
                    system.win = "7";
                    break;
                default:
                    system.win = "NT";
                    break;
            }
        } else if (RegExp["$1"] == "9x") {
            system.win = "ME";
        } else {
            system.win = RegExp["$1"];
        }
    }
}
3.3.2 识别移动设备
var client = function () {
    var system = {
        win: false,
        mac: false,
        x11: false,
        
        // 移动设备
        iphone: false,
        ipod: false,
        ipad: false,
        ios: false,
        android: false,
        nokiaN: false,
        winMobile: false
    };

    //检测移动设备
    system.iphone = ua.indexOf("iPhone") > -1;
    system.ipod = ua.indexOf("iPod") > -1;
    system.ipad = ua.indexOf("iPad") > -1;
    system.nokiaN = ua.indexOf("NokiaN") > -1;
    //windows mobile
    if (system.win == "CE") {
        system.winMobile = system.win;
    } else if (system.win == "Ph") {
        if (/Windows Phone OS (d+.d+)/.test(ua)) {
            system.win = "Phone";
            system.winMobile = parseFloat(RegExp["$1"]);
        }
    }
    //检测 iOS 版本
    if (system.mac && ua.indexOf("Mobile") > -1) {
        if (/CPU (?:iPhone )?OS (d+_d+)/.test(ua)) {
            system.ios = parseFloat(RegExp.$1.replace("_", "."));
        } else {
            system.ios = 2; //不能真正检测出来,所以只能猜测
        }
    }
    //检测 Android 版本
    if (/Android (d+.d+)/.test(ua)) {
        system.android = parseFloat(RegExp.$1);
    }

    return {
        engine: engine,
        browser: browser,
        system: system
    };
}();
3.3.3 识别游戏系统

除了移动设备之外,视频游戏系统中的 Web 浏览器也开始日益普及。任天堂 WiiPlaystation 3 或者内置 Web 浏览器,或者提供了浏览器下载。Wii 中的浏览器实际上是定制版的 Opera,是专门为 Wii Remote 设计的。Playstation 的浏览器是自己开发的,没有基于前面提到的任何呈现引擎。这两个浏览器中的用户代理字符串如下所示:

Opera/9.10 (Nintendo Wii;U; ; 1621; en)
Mozilla/5.0 (PLAYSTATION 3; 2.00)

第一个字符串来自运行在 Wii 中的 Opera,它忠实地继承了 Opera 最初的用户代理字符串格式。第二个字符串来自 Playstation 3,虽然它为了兼容性而将自己标识为 Mozilla 5.0,但并没有给出太多信息,而且设备名称全部使用了大写字母。

var client = function () {
    var system = {
        win: false,
        mac: false,
        x11: false,
        
        // 移动设备
        iphone: false,
        ipod: false,
        ipad: false,
        ios: false,
        android: false,
        nokiaN: false,
        winMobile: false,

        // 游戏系统
        wii: false,
        ps: false
    };

    //检测游戏系统
    system.wii = ua.indexOf("Wii") > -1;
    system.ps = /playstation/i.test(ua);

    return {
        engine: engine,
        browser: browser,
        system: system
    };
}();
3.4 完整代码

UserAgentDetection.js

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

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

相关文章

  • 户端检测用户代理检测navigator.userAgent

    摘要:检测脚本的基本代码结构如下所示呈现引擎具体的版本号检测呈现引擎全局变量,用于保存相关信息。如果检测到了哪个呈现引擎,那么就以浮点数值形式将该引擎的版本号写入相应的属性。 前言 前端这东西,各种先有事实后有标准。不管是各大浏览器老哥各自为政,还是w3c姗姗来迟,既有事实标准难以更改。虽说多方割据,互相竞争,总比一家独大,爱更不更来得好。但却苦了我们这些平头小码农?,颈椎病又加深了啊。 ...

    luck 评论0 收藏0
  • JavaScript 户端检测——“用户代理检测”的注意要点

    摘要:用户代理检测通过的属性访问。在服务器端,通过检测用户代理字符串来确定用户使用的浏览器是一种常用的做法但在客户端,用户代理检测一般为最低优先级。目前只要检测五大呈现引擎即可和。 用户代理检测 通过 JavaScript 的 navigator.userAgent 属性访问。在服务器端,通过检测用户代理字符串来确定用户使用的浏览器是一种常用的做法;但在客户端,用户代理检测一般为最低优先级。...

    instein 评论0 收藏0
  • 《JavaScript高级程序设计》笔记:户端检测(九)

    摘要:由于怪癖检测无法精确地检测特定的浏览器和版本。用户代理检测需要特殊的技巧,特别是要注意会隐瞒其用户代理字符串的情况。而在客户端,用户代理检测一般被当作一种万不得已的做法,其优先级排在能力检测和怪癖检测之后。 能力检测 在编写代码之前先检测特定浏览器的能力。例如,脚本在调用某个函数之前,可能要先检测该函数首付存在。这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意...

    aaron 评论0 收藏0
  • 《JavaScript高级程序设计》(第3版)读书笔记 第9章 户端检测

    摘要:用户代理检测用户代理检测是争议最大的客户端检测技术。第二个要检测是。由于实际的版本号可能会包含数字小数点和字母,所以捕获组中使用了表示非空格的特殊字符。版本号不在后面,而是在后面。除了知道设备,最好还能知道的版本号。 检测Web客户端的手段很多,各有利弊,但不到万不得已就不要使用客户端检测。只要能找到更通用的方法,就应该优先采用更通用的方法。一言蔽之,先设计最通用的方案,然后再使用特定...

    ispring 评论0 收藏0
  • JavaScript 户端检测(高程三)

    摘要:客户端检测方式能力检测怪癖检测用户代理检测能力检测最常用也是最为人们广泛接受的客户端检测形式是能力检测又称特性检测。在可能的情况下,尽量使用进行能力检测。 客户端检测方式 能力检测 怪癖检测 用户代理检测 能力检测 最常用也是最为人们广泛接受的客户端检测形式是能力检测(又称特性检测)。能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力。采用这种方式不必顾及特定的浏览器如何...

    msup 评论0 收藏0

发表评论

0条评论

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