《JavaScript高級程序設計》(第3版)讀書筆記 第9章 客戶端檢測

  • 檢測Web客戶端的手段不少,各有利弊,但不到萬不得已就不要使用客戶端檢測。只要能找到更通用的方法,就應該優先採用更通用的方法。一言蔽之,先設計最通用的方案,而後再使用特定於瀏覽器的技術加強方案

能力檢測

  • 能力檢測(又稱特性檢測),是普遍爲人接受的客戶端檢測形式,目標不是識別特定的瀏覽器,而是識別瀏覽器的能力。
  • IE5.0以前的版本不支持document.getElementById()這個DOM方法,儘管可使用非標準的document.all屬性實現相同的目的。因而就有相似下面的能力檢測代碼
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!");
  }
}
  • 一個特性存在,不必定另外一個特性也存在
function getWindowWidth() {
  if (document.all) {
    // 假設這裏是IE瀏覽器
    return document.documentElement.clientWidth;     // 錯誤的用法
  } else {
    return window.innerWidth;
  }
}

更可靠的能力檢測

// 這不是能力檢測——只是檢測了是否存在相應的方法
function isSortable(object) {
  return !!object.sort;
}

// 任何包含sort屬性的對象都會返回true
var result = isSortable({sort: true});
// 這樣更好:檢測sort是否是函數
function isSortable(object) {
  return typeof object.sort == "function";
}
  • 在可能的狀況下,儘可能使用typeof操做符進行能力檢測。特別是,宿主對象沒有義務讓typeof返回合理的值。最使人髮指的事就發生在 IE 中。大多數瀏覽器在檢測到document.createElement()存在時,都會返回true
// 在IE8及以前版本不行
function hasCreateElement() {
  return typeof document.createElement == "function";
}
  • IE8- 中這個函數返回false,由於typeof document.createElement返回的的是「object」,而不是「function」。如前所述,DOM對象是宿主對象,IE及更早版本中的宿主對象是經過COM而非JScript實現的。所以,document.createElement()函數確實是一個COM對象。IE9糾正了這個問題,對全部DOM方法都返回"function"。

能力檢測,不是瀏覽器檢測

// 還不夠具體
var isFirefox = !!(navigator.vendor && navigator.vendorSub);

// 假設過頭了
var isIE = !!(document.all && document.uniqueID);
  • 檢測某個或幾個屬性並不可以肯定瀏覽器。navigator.vendornavigator.vendorSub確實是Firefox的獨有屬性,可是後來Safari也依樣畫葫蘆實現了相同的屬性。document.all && document.uniqueID這兩個屬性是早期IE的獨有屬性,目前還存在,但不保證將來IE不會去掉。
  • 根據瀏覽器不一樣將能力組合起來是更可取的方式。若是你知道本身的應用程序須要使用某些特定的瀏覽器特性,那麼最好是一次性檢測全部相關特性,而不是分別檢測。
// 肯定瀏覽器是否支持 Netscape風格的插件
var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);

// 肯定瀏覽器是否具備DOM1級規定的能力
var hasDOM1 = !!(document.getElementById && document.createElement && document.getElementsByTagName);
  • 在實際開發中,應該將能力檢測做爲肯定下一步解決方案的依據,而不是用它來判斷用戶使用的是什麼瀏覽器。

怪癖檢測

  • 怪癖檢測 (quirks detection) 的目標是識別瀏覽器的特殊行爲。但與能力檢測不一樣,怪癖檢測是想知道瀏覽器存在什麼缺陷(也就是bug)。
  • 例如IE8及之前版本存在一個bug,即若是某個實例屬性與[[Enumerbale]]標記爲false的某個原型屬性同名,那麼該實例將不會出如今for-in循環中。
// 檢測上述怪癖的代碼
var hasDontEnumQuirk = function() {

  var o = { toString: function() {} };
  for (var prop in o) {
    if (prop == "toString") {
      return false;
    }
  }
  return true;
}
  • 另外一個常常須要檢測的怪癖是Safari 3 之前版本會枚舉被隱藏的屬性。
var hasEnumShadowsQuirk = function() {

  var o = { toString: function() {} };
  var count = 0;
  for (var prop in o) {
    if (prop == "toString") {
      count++;
    }
  }
  // 若是瀏覽器存在這個bug
  // 就會返回兩個 toString 的實例
  return (count > 1);
}
  • 因爲檢測怪癖涉及運行代碼,所以建議僅檢測那些對你有直接影響的怪癖,並且最好在腳本一開始就執行此類檢測。

用戶代理檢測

  • 用戶代理檢測是爭議最大的客戶端檢測技術。
  • 用戶代理檢測經過用戶代理字符串來肯定實際使用的瀏覽器。在每一次HTTP請求過程當中,用戶代理字符串是做爲響應首部發送的,並且該字符串能夠經過JavaScript的navigator.userAgent屬性訪問。
  • 在服務端,經過檢測用戶代理字符串來肯定用戶使用的瀏覽器是一種經常使用的並且廣爲接受的作法。而在客戶端,用戶代理檢測通常被當作一種萬不得已採用的作法,其優先級排在能力檢測和怪癖檢測以後。
  • 有關的爭議不得不提電子詐騙(spoofing)。瀏覽器經過在本身的用戶代理字符串加入一些錯誤或誤導信息,來達到欺騙服務器的目的。

用戶代理字符串的歷史

javascript

用戶代理字符串檢測技術

識別呈現引擎

  • 確切的紙袋瀏覽器的名字和版本不如確切的紙袋它使用的是什麼引擎。
  • 咱們要編寫腳本將五大呈現引擎: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
  };
}();
  • 匿名函數內定義了一個局部變量engin,包含默認設置的對象字面量,每一個呈現引擎都對應着一個屬性,默認值爲0.若是檢測到了哪一個呈現引擎,那麼就以浮點數值形式,將引擎的版本號寫入相應的屬性。而呈現引擎的完整版本(一個字符串)則被寫入 ver 屬性。
if (client.engine.ie) {
  // 若是是IE client.ie 應該大於0
  ...
} else if (client.engine.gecko > 1.5) {
  if (client.engine.ver === "1.8.1") {
    // 針對這個版本的操做
    ...
  }
}
  • 第一個要檢測是Opera,咱們不相信Opera,是由於其用戶代理字符串不會將本身標識爲Opera。要識別Opera,必須檢測window.opera對象。Opera5+都有這個版本。在Opera7.6+中調用version()方法能夠返回一個表示瀏覽器版本的字符串。
if (window.opera) {
  engine.ver = window.opera.version();
  engine.opera = parseFloat(engine.ver);
}
  • 第二個要檢測是Webkit。由於WebKit用戶代理字符串中包含"Gecko"和"KHTML"這兩個子字符串,因此若是首先檢測它們可能會得出錯誤的結論。不過「AppleWebKit"是獨一無二的。
  • iPhone 6s Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1
  • Chrome 74 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
  • 因爲實際的版本號可能會包含數字、小數點和字母,因此捕獲組中使用了表示非空格的特殊字符 \S 。用戶代理字符串中的版本號與下一部分的分隔是一個空格,所以這個模式能夠保證捕獲全部版本信息。
var ua = navigator.userAgent;

if (/AppleWebKit\/(\S+)/.test(ua)) {
  // \S 表示非空格的特殊字符
  // \S+ 表示不包含空格的子字符串
  // 小括號表示將此子字符串加入捕獲組
  // RegExp["$1"] 表示捕獲組的第一個元素,即爲上面描述的子字符串
  engine.ver = RegExp["$1"];
  engine.webkit = parseFloat(engine.ver);
}
  • 接下來要測試的是KHTML。一樣,字符串中也包含「Gecko」,所以在排除KHTML以前,咱們沒法準確檢測基於GECKO的瀏覽器。格式與Webkit差很少。此外因爲Konqueror3.1及更早版本中不包含KHTML的版本,故而就要使用Konqueror代替。
if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)) {
  engine.ver = RegExp["$1"];
  engine.khtml = parseFloat(engine.ver);
}
  • 下面檢測Gecko。版本號不在Gecko後面,而是在 「rv:」後面。好比WindowsXP 下的Firefox2.0.0.11:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
// 在上面的字符串中實際匹配的是"rv:1.8.1.11) Gecko/20071127"
// gecko的版本號位於 rv: 與一個閉括號之間,所以爲了提取出這個版本號
// [^\)]+ 就是將 rv: 以後的字符串排除 ) 閉括號 以後加入捕獲組
// 正則表達式要查找全部不是閉括號的字符,還要查找字符串"Gecko/"後跟8個數字
if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)) {
  engine.ver = RegExp["$1"];
  engine.gecko = parseFloat(engine.ver);
}
  • 最後一個檢測IE。IE的版本號位於字符串"MSIE"的後面、一個分號的前面
// 五個呈現引擎完整的檢測代碼以下
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) || /Konqueror\/([^;]+)/.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);
}

識別瀏覽器

  • 識別呈現引擎大多數狀況下足覺得咱們採起正確的操做提供了依據(pc上,移動端大部分都不行)。
  • 蘋果公司的Safari瀏覽器和谷歌的Chrome瀏覽器都是用Webkit做爲呈現引擎,但它們的JavaScript引擎卻不一樣。
// 咱們的檢測代碼須要添加瀏覽器的檢測
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
  };
}();
  • 因爲大多數瀏覽器與其呈現引擎密切相關,因此下面的檢測瀏覽器代碼和檢測呈現引擎的代碼是混合在一塊兒的。
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 = RegExp["$1"];
  engine.ie = parseFloat(engine.ver);
}
  • 有了上述代碼以後,咱們就能夠編寫如下邏輯
if (client.engine.webkit) {
  if (client.browser.chrome) {
    // 執行鍼對Chrome的代碼
  } else if (client.browser.safari) {
    // 執行鍼對Safari的代碼
  }
} else if (client.engine.gecko) {
  if(client。browser.Firefox) {
    // 執行鍼對Firefox的代碼
  } else {
    // 執行鍼對其餘Gecko瀏覽器代碼
  }
}

識別平臺

  • 瀏覽器針對不一樣平臺會有不一樣的版本,如Safari Firefox Opera , 在不一樣平臺下可能會有不一樣問題。目前三大主流平臺是 Window/Mac/Unix(包括各類Linux)。
// 咱們的檢測代碼須要添加平臺的檢測
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 system = {
    win: false,
    mac: false,
    // Unix
    x11: false
  }

  // 在此檢測呈現引擎、平臺和設備
  ...

  return {
    engine: engine,
    browser: browser,
    system: system
  };
}();
  • 檢測navigator.platform來肯定平臺,在不一樣瀏覽器中給出的值都是一致的,檢測起來很是直觀
var p = navigator.platform;
// window 可能有 Win32 和 Win64
system.win = p.indexOf("Win") == 0;
system.win = p.indexOf("Mac") == 0;
system.win = (p.indexOf("U11") == 0) || (p.indexOf("Linux") == 0);

識別Windows系統

  • 在WindowsXP以前,Windows有分別針對家庭和商業用戶的兩個版本。針對家庭的分別是Windows95和WindowsME。針對商業的一直叫WindowsNT,最後因爲市場緣由更名爲Windows2000。這兩個產品線後來又合併成一個由WindowsNT發展而來的公共代碼基,表明產品就是WindowsXP。
  • 原著編撰年代較早(2012.3),筆記這裏只列舉WindowsXP之後的代碼,並補充Windows10
版本 IE 4+ Gecko Opera < 7 Opera 7+ WebKit
XP "Windows NT 5.1" "Windows NT 5.1" "WindowsXP" "Windows NT 5.1" "Windows NT 5.1"
Vista "Windows NT 6.0" "Windows NT 6.0" n/a "Windows NT 6.0" "Windows NT 6.0"
7 "Windows NT 6.1" "Windows NT 6.1" n/a "Windows NT 6.1" "Windows NT 6.1"
10 "Windows NT 10.0" "Windows NT 10.0" n/a "Windows NT 10.0" "Windows NT 10.0"
  • 忽略掉Opera 7- 的用戶和WindowsXP之前的系統,將原著代碼修改以下:
if (system.win) {
  // 好比在Windows10的Chrome裏,userAgent返回字符串
  // Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
  // 咱們要提取兩個子字符串 'NT' 和 '10.0'
  // ([^dows]{2}) 表示排除包含'dows'的字符以後的後2位字符 加入捕獲組 $1
  // (\d+\.\d+) 表示 x.x(x) 形式的版本號加入捕獲組 $2
  if (/Windows ([^dows]{2})\s?(\d+\.\d+)?/.test(ua)) {
    if (RegExp["$1"] == "NT") {
      switch (RegExp["$2"]) {
        case "5.1":
          system.win = "XP";
          break;
        case "6.0":
          system.win = "Vista";
          break;
        case "6.1":
          system.win = "7";
          break;
        case "10.0":
          system.win = "10";
          break;
        default:
          system.win = "NT";
          break;
      }
    } else {
      system.win = RegExp["$1"];
    }
  }
}

識別移動設備

// 咱們在系統變量裏添加移動設備的屬性
var client = function() {
  ...

  var system = {
    win: false,
    mac: false,
    // Unix
    x11: false,

    // 移動設備
    iphone: false,
    ipod: false,
    ipad: false,
    ios: false,
    android: false,
    nokiaN: false,
    winMobile: false
  }

  // 在此檢測呈現引擎、平臺和設備
  ...

  return {
    engine: engine,
    browser: browser,
    system: system
  };
}();
  • 一般的檢測字符串"iphone", "ipod", "ipad", 就能夠分別設置相應屬性的值了。
system.iphone = ua.indexOf("iPhone") > -1;
system.ipod = ua.indexOf("iPod") > -1;
system.ipad = ua.indexOf("iPad") > -1;
  • 除了知道iOS設備,最好還能知道iOS的版本號。在iOS3以前,用戶代理字符串只包含"CPU like Mac OS",後來iPhone中又改爲"CPU iPhone OS 3_0 like Mac OS X",iPad中又改爲"CPU OS 3_2 like Mac OS X"。
  • 檢查系統是否是 Mac OS、字符串中是否存在"Mobile",能夠保證不管是什麼版本,system.ios中都不會是 0
// 檢測iOS版本
if (system.max && ua.indexOf("Mobile") > -1) {
  if (/CPU (?:iPhone )?OS (\d+_\d+)/.test(ua)) {
    system.ios = parseFloat(RegExp.$1.repalce("_", "."));
  } else {
    system.ios = 2;   // 不能準確判斷只能靠猜
  }
}
  • 檢測Android操做系統也很簡單,搜索字符串"Android"並取得緊跟其後的版本號
// 檢測Android版本
if (/Android (\d+\.\d+)/.test(ua)) {
  system.android = parseFloat(RegExp.$1);
}
  • 遠在天國的諾基亞,略
  • 在天國門口的Windows Phone , 略

識別遊戲系統

  • 除了移動設備以外,視頻遊戲系統中的Web瀏覽器也開始日益普及。任天堂Wii和PlayStation3+等等。
  • Wii的瀏覽器其實是定製版的Opera,專門爲Wii Remote設計的。用戶代理字符串:Opera/9.10 (Nintendo Wii;U; ; 1621; en)
  • PlayStation的瀏覽器是本身開發的,沒有基於前面提到的任何呈現引擎。用戶代理字符串:Mozilla/5.0 (PLAYSTATION 3; 2.00)
// 咱們在系統變量裏添加遊戲設備的屬性
var client = function() {
  ...

  var system = {
    ...

    // 遊戲系統
    wii: false,
    ps: false
  }

  // 在此檢測呈現引擎、平臺和設備
  ...

  return {
    engine: engine,
    browser: browser,
    system: system
  };
}();
  • 檢測前述遊戲系統的代碼以下
system.wii = ua.indexOf("Wii") > -1;
// ps要忽略大小寫
system.ps = /playstation/i.test(ua);

完整的代碼

// 我的作了部分修改 修改時間 2019.5.17
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 system = {
    win: false,
    mac: false,
    // Unix
    x11: false,

    // 移動設備
    iphone: false,
    ipod: false,
    ipad: false,
    ios: false,
    android: false,
    nokiaN: false,
    winMobile: false,

    // 遊戲系統
    wii: false,
    ps: false
  }

  // 在此檢測呈現引擎、平臺和設備
  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 = RegExp["$1"];
    engine.ie = parseFloat(engine.ver);
  }

  // 檢測瀏覽器
  browser.ie = engine.ie;
  browser.opera = engine.opera;

  // 檢測平臺
  var p = navigator.platform;
  system.win = p.indexOf("Win") == 0;
  system.win = p.indexOf("Mac") == 0;
  system.win = (p.indexOf("U11") == 0) || (p.indexOf("Linux") == 0);

  // 檢測Windos操做系統
  // 排除WindosXP之前的系統
  if (system.win) {
    if (/Windows ([^dows]{2})\s?(\d+\.\d+)?/.test(ua)) {
      if (RegExp["$1"] == "NT") {
        switch (RegExp["$2"]) {
          case "5.1":
            system.win = "XP";
            break;
          case "6.0":
            system.win = "Vista";
            break;
          case "6.1":
            system.win = "7";
            break;
          case "10.0":
            system.win = "10";
            break;
          default:
            system.win = "NT";
            break;
        }
      } else {
        system.win = RegExp["$1"];
      }
    }
  }

  // 移動設備
  // 剔除了諾基亞和windows phone
  system.iphone = ua.indexOf("iPhone") > -1;
  system.ipod = ua.indexOf("iPod") > -1;
  system.ipad = ua.indexOf("iPad") > -1;

  // 檢測iOS版本
  if (system.max && ua.indexOf("Mobile") > -1) {
    if (/CPU (?:iPhone )?OS (\d+_\d+)/.test(ua)) {
      system.ios = parseFloat(RegExp.$1.repalce("_", "."));
    } else {
      system.ios = 2;   // 不能準確判斷只能靠猜
    }
  }

  // 檢測Android版本
  if (/Android (\d+\.\d+)/.test(ua)) {
    system.android = parseFloat(RegExp.$1);
  }

  // 遊戲系統
  system.wii = ua.indexOf("Wii") > -1;
  system.ps = /playstation/i.test(ua);

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

使用方法

  • 用戶代理檢測是客戶端檢測的最後一個選項。只要可能,都應該優先採用能力檢測和怪癖檢測。用戶代理檢測通常適用於下列情形:html

    • 不能直接準確的使用能力檢測或怪癖檢測。例如某些瀏覽器實現了爲未來功能預留的存根函數(stub)。在這種狀況下,僅測試相應的函數是否存在還得不到足夠信息。
    • 同一款瀏覽器在不一樣平臺下具有不一樣的能力。
    • 爲了跟蹤分析等目的須要知道確切的瀏覽器。
相關文章
相關標籤/搜索