1. 程式人生 > >Javascript高階程式設計學習筆記(34)—— 客戶端檢測(3)使用者代理檢測

Javascript高階程式設計學習筆記(34)—— 客戶端檢測(3)使用者代理檢測

使用者代理檢測

前面的文章介紹的是如何檢測瀏覽器對某一功能的支援情況

但是在實踐中我們有些時候免不了需要知道使用者到底是用的什麼瀏覽器對我們的站點進行訪問

這也是統計使用者行為的一部分

 

使用者代理檢測這種方式就是用於檢測使用者訪問所使用的瀏覽器的

那麼如何進行檢測呢?

我之前的文章,講JS的navigator物件的時候,其中有個 userAgent 屬性

這個屬性在每次http請求中都會攜帶在請求頭中,這也是我們常說的使用者代理字串

 

但是要注意的是,這種客戶端檢測的優先順序應該排在 怪癖檢測、能力檢測之後

作為一種萬不得已的手段

為什麼呢?因為這和 電子欺騙

有關

所謂電子欺騙,就是指瀏覽器通過在使用者代理字串中加入錯誤、誤導資訊來影響伺服器對使用者的判斷

為什麼瀏覽器要這樣做呢?

 

這就和web早期的發展有關,在早期的發展過程中,使用者代理字串一開始是統一的

但是到了IE4微軟希望佔據更大的市場,並且希望體現IE的獨立性,所以使用者代理字串中就出現了IE自己的標識

這樣做使當時的 Netscape(當時最受歡迎的瀏覽器)很不爽,所以其合作公司通過在服務端檢測使用者代理字串,來區分使用者

以此來拒絕IE使用者的訪問

而IE當然不肯善罷甘休,所以就在使用者代理字串中,在不違反標準的情況下添加了混淆資訊

其它瀏覽器廠商紛紛效仿IE

所以檢測使用者代理字串來判斷瀏覽器存在一定的風險,準確性也不高

這種方法也就成為了客戶端檢測的備選方法

 

 和之前一樣,這裡還是給出一段檢測程式碼

PS:書中檢測的只檢測到IE11,然而edge的部分並沒有,所以這一部分是我自己測試的,有可能會有些問題

 

使用者代理字串檢測函式

// 無需引數
// 返回一個包含瀏覽器資訊的物件
function getClient() {
        var engine = {
            // 儲存瀏覽器引擎
            ie: 0,
            gecko: 0,
            webkit: 
0, khtml: 0, opera: 0, ver: null // 具體版本 }; var browser = { // 瀏覽器 ie: 0, firefox: 0, safari: 0, konqueror: 0,// 夸克 opera: 0, chrome: 0, ver: null // 瀏覽器版本 }; var system = { // PC 端 win: false, mac: false, xll: false, // linux // 移動裝置 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){// 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); // 判斷谷歌和safari if(/Edge\/(\S+)/.test(ua)){// Edge 偽裝的很好 所以先檢測 engine.ver = browser.ver = RegExp["$1"]; engine.webkit = 0; engine.ie = "Edge"; browser.ie = "Edge"; }else 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.konqueror = parseFloat(engine.ver); }else if(/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){ engine.ver = RegExp["$1"]; engine.gecko = parseFloat(engine.ver); // 識別火狐 if(/Firefox\/(\S+)/.test(ua)){ browser.ver = RegExp["$1"]; browser.firefox = parseFloat(browser.ver); } }else if(/MSIE ([^;]+)/.test(ua)||(/Trident\/(\S+)/.test(ua)&&/rv:([^\)]+)\)/.test(ua))){ // 識別IE engine.ver = browser.ver = RegExp["$1"]; engine.ie = browser.ie = parseFloat(engine.ver); } // 平臺檢測 var p = navigator.platform; system.win = p.indexOf("Win") === 0; system.mac = p.indexOf("Mac") === 0; system.xll = (p === "Xll") || (p.indexOf("Linux") === 0); // windows版本 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 = RegExp.$2; break; } }else if(RegExp["$1"] === "9x"){ system.win = "ME"; }else{ system.win = RegExp["$1"]; } } } // 移動裝置 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 Phone if(system.win ==="CE"){ system.winMobile = system.win; }else if(system.win === "Ph"){ if(/Windows Phone OS (\d+.\d+)/.test(ua)||/Windows Phone (\d+.\d+)/.test(ua)){ system.win = "windowsPhone"; 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; // 具體版本無法測試,預設為2 } } // 檢測安卓版本 if(/Android (\d+\.\d+)/.test(ua)&& !system.winMobile){ system.android = parseFloat(RegExp.$1); } // 平臺檢測 system.wii = ua.indexOf("Wii") > -1; system.ps = /playstation/i.test(ua); return { engine: engine, browser: browser, system: system }; }