JavaScript 使用者代理檢測(瀏覽器型別檢測,執行平臺檢測等) 規範程式碼
客戶端檢測
客戶端檢測很直觀地分為: 能力檢測,怪癖檢測和使用者代理檢測
- 能力檢測是檢驗所執行的平臺是否支援指定的函式,程式碼或者功能。建議需要才檢測的原則,可將所需要的功能進行統一檢測到初始化中,這樣可以實現能力檢測的統一管理。
- 怪癖檢測是檢驗所執行的平臺或者引擎是否有指定的bug,該方法主要是為了避免瀏覽器的某些知名的BUG,但是一般開發者不會遇到。
- 使用者代理檢測是檢驗JavaScript的執行程式碼的呈現引擎,瀏覽器等等而實現的方法,主要用於實現多平臺多功能。
使用者代理檢測規範程式碼
本規範程式碼參考自Nicholas C.Zakas所著的Professional JavaScript for Web Developers,可實現識別 呈現引擎種類,瀏覽器種類, 執行平臺種類, 移動裝置種類 和 遊戲系統種類 五種類別檢測。
廢話不說,放原始碼。下面我將在程式碼中加入高效的註釋來解釋程式碼的執行邏輯,以及在程式碼最後進行更為詳細的分步介紹
var client = function(){
//rendering engines 呈現引擎的區域性變數,在此加入經典的五類引擎
var engine = {
ie: 0,
gecko: 0,
webkit: 0,
khtml: 0,
opera: 0,
//more engine
ver: null
};
//browsers 瀏覽器類別的區域性變數,加入經典的六類瀏覽器
var browser = {
ie: 0,
firefox: 0,
safari: 0,
konq: 0,
opera: 0,
chrome: 0,
//specific version
ver: null
};
//platform/device/OS 執行平臺的區域性變數,加入經典的三類電腦平臺,七類移動端平臺以及兩類遊戲平臺
var system = {
win: false,
mac: false,
x11: false,
//mobile devices
iphone: false,
ipod: false,
ipad: false,
ios: false,
android: false,
nokiaN: false,
winMobile: false,
//game systems
wii: false,
ps: false
};
//detect rendering engines/browsers 該部分用於識別引擎和瀏覽器
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);
//figure out if it's Chrome or 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 {
//approximate version
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);
//determine if it's 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);
}
//detect browsers
browser.ie = engine.ie;
browser.opera = engine.opera;
//detect platform 識別執行平臺
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
//detect windows operating systems
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"];
}
}
}
//mobile devices
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"]);
}
}
//determine iOS version
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; //can't really detect - so guess
}
}
//determine Android version
if (/Android (\d+\.\d+)/.test(ua)){
system.android = parseFloat(RegExp.$1);
}
//gaming systems
system.wii = ua.indexOf("Wii") > -1;
system.ps = /playstation/i.test(ua);
//return it
return {
engine: engine,
browser: browser,
system: system
};
}();
在程式碼執行最後,通過一個匿名函式返回結果給 client 變數。
下面是我在windows10 使用 chrome執行的結果。
型別 | 版本 |
---|---|
engine.webkit: 537.36 | engine.ver: “537.36” |
browser.chrome: 85 | browser.ver: "85.0.4183.83" |
system.win: “NT” |
程式碼輸出和實現的解釋
識別呈現引擎(ie,gecko,webkit,khtml,opera)
首先使用者代理字串對於不同的瀏覽器和不同的平臺來說變化非常多,下面來列舉一些經典的使用者代理字串的例子。
引擎/瀏覽器 | 使用者代理字串 |
---|---|
WebKit / Chrome | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 |
Gecko / Firfox | Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0 |
WebKit / Safari | Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/124 (Khtml, Kike Gecko) Safari/125.1 |
Opera | Mozilla/4.0 (compatible; MSIE 6.0); Windows NT 5.1; en) Opera 9.50 |
Opera
Opera經常將自己標識為其它引擎,因此我們先檢測它,並且不使用使用者代理字串,要使用windows.opera函式。
if (window.opera){
engine.ver = browser.ver = window.opera.version();
engine.opera = browser.opera = parseFloat(engine.ver);
}
Webkit
根據使用該引擎的瀏覽器的代理字串特點,主要去識別 AppleWebKit 字串,正規表示式組主要識別AppleWebKit和後面的版本號。ua是使用者代理字串,程式碼如下:
if (/AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"];
engine.webkit = parseFloat(engine.ver);
}
KHTML
同理,主要識別 KHTML 字串。ua是使用者代理字串。
if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
engine.ver = browser.ver = RegExp["$1"];
engine.khtml = browser.konq = parseFloat(engine.ver);}
Gecko
包含Gecko的版本號位於字串“rv:”和一個閉括號之間,為了提取這個版本號,需要朝招所有不是閉括號的字元,而且還要查詢字串“Gecko/”後跟的八個數字。正規表示式為:“/rv:([^)]+)) Gecko/\d{8}/”。ua是使用者代理字串。具體程式碼為:
if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
engine.ver = RegExp["$1"];
engine.gecko = parseFloat(engine.ver)};
識別瀏覽器
由於Chrome和Safari使用同樣的WebKit引擎,因此區分這兩個瀏覽器很重要。在提取Chrome的版本號時,需要查詢字串“Chrome/”並取得該字串後面的數值。而提取Safari的版本號時,則需要查詢字串“Version/”並取得其後的數值。如果Safari為3以下的版本,則需要一些備用程式碼。具體程式碼為:
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 {
//approximate version
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;
}
而對於Firefox瀏覽器,我們首先要找到“Firefox/”,然後提取該字串後面的數值。程式碼很簡單:
if (/Firefox\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.firefox = parseFloat(browser.ver);
}
執行平臺識別
通過navigator.platform來進行檢測。具體程式碼為:
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.x11 = (p == "X11") || (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 = "NT";
break;
}
} else if (RegExp["$1"] == "9x"){
system.win = "ME";
} else {
system.win = RegExp["$1"];
}
}
}
識別移動裝置
移動裝置識別也是通過使用者代理字串檢測來實現,實現方式較為簡單。
- iPhone, iPod 和 iPad: 通過indexOf檢測使用者代理字串是否含有該指定字串。其版本號內容較為多變。比如IOS3之前,字串只包含“CPU like Mac OS”, iphone 改成 “CPU iphone OS 3_0 like Mac OS X”, iPad中改為“CPU OS 3_2 like Mac OS X”。因此版本號必須使用正規表示式去搜尋匹配不同的規則。
` 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; //can't really detect - so guess
}
}`
- Android作業系統識別。搜尋字串“Android”並取得緊隨其後的版本號。
if (/Android (\d+\.\d+)/.test(ua)){
system.android = parseFloat(RegExp.$1);
}
- 諾基亞N系列手機:檢測字串中的“NokianN”,並取得緊隨其後的版本號。
- windows mobile:新老版本的windows mobile的system.win的返回值分別為 Ph和CE,因此需要正規表示式的存在。如果system.in的值是“CE”,就說明是老版本的windows Mobile,因此system.winMobile會被設定為相同的值。如果sytem.win的值是“Ph”,那麼這個裝置就可能是window phone7或更新版本。因此使用正規表示式來測試格式和版本號即可。
這個程式碼可以隨著瀏覽器的種類增多慢慢豐富起來,歡迎大家提出寶貴的意見。
相關文章
- 檢測360瀏覽器javascript程式碼例項瀏覽器JavaScript
- js+jquery檢測使用者瀏覽器型號(包括對360瀏覽器的檢測)薦JSjQuery瀏覽器
- JavaScript型別檢測JavaScript型別
- JavaScript學習6:瀏覽器檢測JavaScript瀏覽器
- JavaScript 檢測程式碼執行時間JavaScript
- 跨瀏覽器的JavaScript效能檢測工具瀏覽器JavaScript
- Python程式碼規範性檢測Python
- JavaScript安全的型別檢測JavaScript型別
- javascript 資料型別檢測JavaScript資料型別
- 檢測是否為360瀏覽器?瀏覽器
- 瀏覽器特性檢測框架:MODERNIZR瀏覽器框架
- javascript資料型別檢測方法JavaScript資料型別
- JavaScript中的瀏覽器檢測和DOM基礎JavaScript瀏覽器
- 常見瀏覽器終端檢測瀏覽器
- 瀏覽器開發者工具開啟檢測瀏覽器
- js 型別檢測JS型別
- 【JS】型別檢測JS型別
- 開源一個程式碼規範檢測工具
- js檢測搜狗瀏覽器、百度瀏覽器、微信瀏覽器程式碼例項JS瀏覽器
- javascript矩形碰撞檢測程式碼JavaScript
- JavaScript的資料型別及其檢測JavaScript資料型別
- JavaScript變數型別檢測總結JavaScript變數型別
- 欄位型別檢測指令碼型別指令碼
- 檢測當前瀏覽器是否支援cookie瀏覽器Cookie
- 如何檢測瀏覽器是否安裝flash瀏覽器
- 漏洞型別及檢測型別
- js檢測瀏覽器內容縮放效果程式碼例項JS瀏覽器
- js檢測當前瀏覽器Flash player版本程式碼例項JS瀏覽器
- 映象規範檢測工具釋出
- JavaScript中資料型別檢測方法盤點JavaScript資料型別
- 檢測瀏覽器是否支援HTML5功能瀏覽器HTML
- 好程式設計師web前端培訓分享如何用js檢測瀏覽器型別程式設計師Web前端JS瀏覽器型別
- js檢測資料型別JS資料型別
- 人臉檢測識別,人臉檢測,人臉識別,離線檢測,C#原始碼C#原始碼
- 怎麼檢測瀏覽器劫持,瀏覽器劫持的方法介紹瀏覽器
- 程式碼質量檢測平臺架構設計架構
- 高通平臺怎麼檢測充電器型別為SDP,CDP,DCP型別
- APUS瀏覽器應用整合惡意URL檢測功能,風險網站檢測能力提升20瀏覽器網站