国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

ispring / 2466人閱讀

摘要:用戶代理檢測用戶代理檢測是爭議最大的客戶端檢測技術。第二個要檢測是。由于實際的版本號可能會包含數字小數點和字母,所以捕獲組中使用了表示非空格的特殊字符。版本號不在后面,而是在后面。除了知道設備,最好還能知道的版本號。

檢測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)。瀏覽器通過在自己的用戶代理字符串加入一些錯誤或誤導信息,來達到欺騙服務器的目的。

用戶代理字符串的歷史

用戶代理字符串檢測技術 識別呈現引擎

確切的紙袋瀏覽器的名字和版本不如確切的紙袋它使用的是什么引擎。

我們要編寫腳本將五大呈現引擎: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
  };
}();
使用方法

用戶代理檢測是客戶端檢測的最后一個選項。只要可能,都應該優先采用能力檢測和怪癖檢測。用戶代理檢測一般適用于下列情形:

不能直接準確的使用能力檢測或怪癖檢測。例如某些瀏覽器實現了為將來功能預留的存根函數(stub)。在這種情況下,僅測試相應的函數是否存在還得不到足夠信息。

同一款瀏覽器在不同平臺下具備不同的能力。

為了跟蹤分析等目的需要知道確切的瀏覽器。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109582.html

相關文章

  • JavaScript高級程序設計》(3讀書筆記 4 變量、作用域和內存問題

    摘要:具體說就是執行流進入下列任何一個語句時,作用域鏈就會得到加長語句的塊。如果局部環境中存在著同名的標識符,就不會使用位于父環境中的標識符訪問局部變量要比訪問全局變量更快,因為不用向上搜索作用域鏈。 基本類型和引用類型的值 ECMAscript變量包含 基本類型值和引用類型值 基本類型值值的是基本數據類型:Undefined, Null, Boolean, Number, String ...

    lidashuang 評論0 收藏0
  • JavaScript高級程序設計》(3讀書筆記 8 BOM

    摘要:僅限數值表示新窗口的高度。此時只要檢查這個返回值就可以確定彈窗是否被屏蔽。返回一個布爾值,代表用戶選擇還是返回一個字符串或者,輸入了值并確定,返回字符串,其他方法關閉返回打印查找對話框。 ECMAScript是JavaScript的核心,但如果要在Web中使用JavaScript,那么BOM(瀏覽器對象模型)則無疑才是真正的核心。 W3C為了把瀏覽器中JavaScript最基本的部分...

    AWang 評論0 收藏0
  • JavaScript高級程序設計》(3讀書筆記 1~2

    摘要:表示應該立即下載腳本,但不應妨礙頁面中的其他操作可選。表示通過屬性指定的代碼的字符集。表示腳本可以延遲到文檔完全被解析和顯示之后再執行。實際上,服務器在傳送文件時使用的類型通常是,但在中設置這個值卻可能導致腳本被忽略。 第1章 JavaScript 簡介 雖然JavaScript和ECMAScript通常被人們用來表達相同的含義,但JavaScript的含義比ECMA-262要多得多...

    Corwien 評論0 收藏0
  • JavaScript高級程序設計》(3讀書筆記 3

    摘要:本質上是由一組無序名值對組成的。浮點數值的最高精度是位小數,但在進行計算時其精度遠遠不如證書。例如這是使用基于數值的浮點計算的通病,并非獨此一家數值范圍。 函數名不能使用關鍵字(typeof不行但typeOf可以,區分大小寫) 標識符就是指變量、函數、屬性的名字,或者函數的參數。 第一個字符必須是一個字母、下劃線(_)或者一個美元符號($) 其他字符可以是字母、下劃線、美元符號或...

    renweihub 評論0 收藏0
  • JavaScript高級程序設計》(3讀書筆記 11 DOM拓展

    摘要:對的兩個主要拓展是選擇和。以下插入標記的拓展已經納入了規范。在寫模式下,會根據指定的字符串創建新的子樹,然后用這個子樹完全替換調用元素。在刪除帶有時間處理程序或引用了其他對象子樹時,就有可能導致內存占用問題。 盡管DOM作為API已經非常完善了,但為了實現更多功能,仍然會有一些標準或專有的拓展。2008年之前,瀏覽器中幾乎所有的拓展都是專有的,此后W3C著手將一些已經成為事實標準的專...

    luck 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<