美文网首页JavaScript
《JavaScript高级程序设计》Chapter 9 客户端检

《JavaScript高级程序设计》Chapter 9 客户端检

作者: 云之外 | 来源:发表于2016-09-26 16:13 被阅读120次

Chapter 9 客户端检测

能力检测

  1. 用于识别浏览器的能力,基本模式如下

    if (object.propertyInQuestion) {
        // use object.propertyInQuestion
    }
    
    function getElement(id) {
        if (document.getElementById) {
            return document.getElementById(id);
        } else if (document.all) {
            return document.all[id];
        } else {
            throw new Error('No way to retrieve element');
        }
    }
    
  2. 更可靠的能力检测

    • 确定一个对象是否支持排序(既要检测 sort 属性是否存在,也要检测 sort 属性是否是一个函数)
    function isSortable(object) {
        return typeof object.sort == 'function';
    }
    
    • 尽量使用 typeof 进行能力检测。但是在 IE8 之前的版本中,由于宿主对象是通过 COM 而非 JScript 实现的,所以 document.createElement() 之类的函数是一个 COM 对象,而非函数
    typeof document.createElement == 'function' // 在 IE8- 中为 false
    
    • IE 中类似的 typeof 的行为不标准的例子还有很多。
    • 在浏览器环境下测试任何对象的某个属性是否存在,要使用下面这个函数
    function isHostMethod(object, property) {
        var t = typeof object[property];
        return t == 'function' || (!!(t == 'object' && object[property])) || t == 'unknown;
    
    result = isHostMethod(xhr, 'open'); // true
    

    在 JavaScript 中, !! 操作符通常用于将表达式强制转换为 boolean 类型数据。

  3. 能力检测,不是浏览器检测

    • 检测某个或某几个特性并不能够确定浏览器。
    • 如果已知应用程序需要使用某些特定的浏览器特性,最好一次检测所有的相关特性,而不是分别检测。
    // 检测浏览器是否具有 DOM1 级规定的能力。
    var hasDOM1 = !! (document.getElementById && document.createElement && document.getElementByTagName);
    

怪癖检测

  1. 怪癖检测的目标是识别浏览器的特殊行为。通过怪癖检测,获知浏览器存在什么样的缺陷。

  2. Example: IE8- 中,如果某个实例属性与 [[Enumerable]] 标记为 false 的某个原型属性同名,那么该实例属性将不会出现在 for-in 循环当中。

    var hasDontEnumQuirk = function() {
        var o = {toString: function() {
            for(var prop in o) {
                if(prop == 'toString') {
                    return false;
                }
            }
        }
        return true;
    }();
    
  3. Example: Safari3- 中,会枚举被隐藏的属性。

var hasEnumShadowsQuirk() {
    var o = {toString: function() {
        var count = 0;
        for (var prop in o) {
            if (prop == 'toString') {
                count++;
            }
        }
        return (count > 1);
    }();
3. Example: Safari3- 中,会枚举被隐藏的属性。

```
var hasEnumShadowsQuirk() {
    var o = {toString: function() {
        var count = 0;
        for (var prop in o) {
            if (prop == 'toString') {
                count++;
            }
        }
        return (count > 1);
    }();
```

用户代理检测

  1. 用户代理检测通过检测用户代理字符串来确定实际使用的浏览器。在每一次 HTTP 请求过程中,用户代理字符串是作为相应首部发送的,而且该字符串可以通过 JavaScript 的 navigator.userAgent 属性访问。

    • 在服务器端,用户代理检测被广泛使用。
    • 在客户端,用户代理检测的优先级排在能力检测 / 怪癖检测之后。
  2. 电子欺骗:浏览器通过在自己的用户代理字符串加入一些错误或误导信息,来达到欺骗服务器的目的。

  3. 用户代理字符串

    • RFC2616 规定格式:标识符/产品版本号
    • IE4 ~ IE7:Mozilla/4.0 (平台; MSIE 版本号; 操作系统)
    • IE8:Mozilla/4.0 (compatible; MSIE 版本号; Trident/Trident 版本号)
      • Trident 记号是为了让开发人员知道 IE8 是不是在兼容模式下运行,如果是,则 MSIE 版本号会变成 7。
    • IE9:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
    • IE9 兼容模式:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0)
    • Gecko:Mozilla/Mozilla 版本号 (平台; 加密类型; 操作系统或CPU; 语言; 预先发型版本) Gecko/Gecko 版本号 应用程序或产品/引用程序或产品版本号
      • 具体查手册
    • Firefox4: Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox 4.0.1
    • Webkit:Mozilla/5.0 (平台; 加密类型; 操作系统或CPU; 语言) AppleWebkit/AppleWebkit 版本号 (KHTML, like Gecko) Safari/Safari 版本号
      • 基于 Webkit 的所有浏览器都将自己标识为 Mozilla 5.0
    • Safari3:Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebkit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5
    • Konqueror 略
    • Chrome7:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebkit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7
    • Opera8:Opera/版本号 (操作系统或CPU; 加密类型; 语言)
    • Opera9:Mozilla/5.0 (Windows NT 5.1; U; en-US; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50
      • Opera隐藏了自己的身份,伪装成 Firefox 或 IE,无法将 Opera 与其他浏览器区别开来。
    • Opera10:Opera/9.80 (操作系统或CPU; 加密类型; 语言) Presto/Presto 版本号 Version/版本号
    • iOS 和 Android:同桌面版
  4. 用户代理字符串检测技术

    • 识别呈现引擎

      • 检测五大引擎: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
          };
      }();
      
      • 如果检测到了哪个呈现引擎,就以浮点数值形式将该引擎的版本号写入相应的属性。而呈现引擎的完整版本(是一个字符串),则被写入 ver 属性。
      if(client.engine.ie) {
          // 针对 IE 的代码
      } else if (client.engine.gecko > 1.5) {
          if (client.engine.ver == '1.8.1') {
              // 针对这个版本执行某些代码
          }
      }
      
      • 识别 Opera 必须检测 window.opera 对象。
      if (window.opera) {
          engine.var = window.opera.version();
          engine.opera = parseFloat(engine.ver);
      
      • 识别 WebKit 和 KHTML 见手册。
    • 识别浏览器(具体见文档)

    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 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); 
    
    • 识别移动设备(具体见文档)
    var system = {
        win: false,
        mac: false,
        x11: false,
        
        iphone: false,
        ipod: false,
        ipad: false,
        ios: false,
        android: false,
        nokiaN: false,
        winMobile: 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); 
    
    system.iphone = ua.indexOf('iPhone') > -1;
    system.ipod = ua.indexOf('iPod') > -1;
    system.ipad = ua.indexOf('iPad') > -1;
    system.nokiaN = ua.indexOf('NokiaN') > -1;
    system.winMobile = (system.win == 'CE');
    
    • 识别游戏系统(略)
  5. 完整的代码(看文档)

相关文章

网友评论

    本文标题:《JavaScript高级程序设计》Chapter 9 客户端检

    本文链接:https://www.haomeiwen.com/subject/jguqyttx.html