客户端检测

Posted 一江西流

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了客户端检测相关的知识,希望对你有一定的参考价值。

1.能力检测
//能力检测的目标不是识别浏览器,而是识别浏览器的能力。它对于想知道某个特性是否会按照适当方式行事(而不仅仅是某个特性存在)非常有用。
//采用这种方式不必顾忌特定的浏览器如何如何,只要确定浏览器支持特定的能力,就可以给出解决方案。能力检测基本模式如下:
if(object.propertyInQuestion){
//使用object.propertyInQuestion
}
//例如,IE5.0之前的版本不支持document.getElementById(),可以使用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 retrive element !")
}
}

//在可能的情况下,要尽量使用typeof进行能力检测。
//isHostMethod()用于在浏览器环境下测试任何对象的某个特性是否存在
function isHostMethod(object,property){
var t = typeof object[property];
return t == "function" || (!!(t == "object" && object[property])) || t == "unkown" ;
}

result = isHostMethod(xhr,"open");//true

//能力检测并不是浏览器检测。检测某个或某几个特性并不能确定浏览器。
//确定浏览器是否支持Netscape风格的插件
var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);
//确定浏览器是否具有DOM1级规定的能力
var hasDOM1 = !!(document.getElementById && document.createElement && document.getElementsByTagName);

2.怪癖检测
//怪癖检测的目标是识别浏览器的特殊行为。是想要知道浏览器存在什么缺陷。通常需要运行一小段代码,以确定某一特性不能正常工作。
//如IE8及更早的版本中个存在一个bug,如果某个实例属性与[[Enumerable]]标记为false的某个原型属性同名,那么该实例属性将不会出现在for-in循环中。
var hasDontEnumQuirk = function(){
var o = { toString :function(){} };
for (var prop in o){
if(prop == "toString"){
return false;
}
}

return true;
}();
//Safari3以前版本会枚举被隐藏的属性。
function hasEnumShadowsQuirk = function(){
var o = { toString : function(){} };
var count = 0;
for (var prop in o){
if(prop == "toString"){
count ++;
}
}

return (count > 1);
}();

3.用户代理检测
//通过检测用户代理字符串来确定实际使用的浏览器。在每一次HTTP请求过程中,
//用户代理字符串(指明浏览器的名称和版本号)是作为响应头部发送的,
//可以通过navigator.userAgent属性访问。(这种方式比较常用于服务端,客户端并不常用)
//IE的引擎是Trident,Firefox->Gecko,Safari->Webkit(是Khtml的一个分支,后来独立出来)
//Chrome->Webkit,Opera以前是Presto现在是Webkit
//移动操作系统android/ios默认的浏览器都基于Webkit

// 用户代理字符串检测技术
// client用于保存相关信息
var client = function(){
// 1.识别呈现引擎
var engine = {
//呈现引擎
ie: 0,
gecko: 0,
webkit: 0,
opera: 0,
// 具体的版本号
ver: null
};
//2.识别浏览器
var browser = {
//浏览器
ie: 0,
firefox: 0,
safari: 0,
konq: 0,
opera: 0,
chrome: 0,
//具体的版本号
ver: null
};
//3.识别平台
var system = {
win: false, //表示window平台
mac: false, //表示Mac平台
xll: false //表示Unix平台

//5.识别移动设备
iphone: false,
ipod: false,
ipad: false,
ios: false,
andriod: false,
nokiaN: false,
winMobile: false,

//6.识别游戏系统 Wii、PlayStation
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)){//第二步是检测Webkit,因为它的用户代理字符串中包含“gecko”和“KHTML”,如果首先检测它可能会得出错误结论。
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)){//第三步要检测的是KHTML,同样KHTML也带有“Gecko”,所以在排除KHTML之前无法检测基于gecko的浏览器
engine.ver = browser.ver = RegExp["$1"];
engine.khtml = browser.konq = parseFloat(engine.ver);
}else if(/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){//第四步检测Gecko,因为它的用户代理字符串中会出现"rv:"。
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)){//最后一步检测IE
engine.ver = browser.ver = RegExp["$1"];
engine.ie = browser.ie = parseFloat(engine.ver);
}

//检测浏览器
browser.ie = engine.ie;
browser.opera = engine.opera;

//检测平台
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.xll = (p.indexOf("Xll") == 0 || (p.indexOf("Linux") == 0));

//4.识别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"];
}
}
}
//移动设备
system.iphone = ua.indexOf("iPhone") > -1;
system.ipod = ua.indexOf("iPod") > -1;
system.ipad = ua.indexOf("iPad") > -1;
system.nokiaN = ua.indexOf("NokiaN") > -1;

if(system.win == "CE"){//检测Windows Phone
system.winMobile = system.win;
if(/Windows Phone OS (\d+.\d+)/.test(ua)){
system.win = "Phone";
system.winMobile = parseFloat(RegExp["$1"]);
}
}

if(system.mac && ua.indexOf("Mobile") > -1){//检测iOS版本
if(/CPU (?:iPhone )?OS (\d+_\d+)/.test(ua)){
system.ios = parseFloat(RegExp.$1.replace("_","."));
}else{
system.ios = 2;//不能正真检测出来,只能猜
}
}

if(/Andriod (\d+\.\d+)/.test(ua)){//检测Andriod版本
system.andriod = parseFloat(RegExp.$1);
}

//检测游戏系统
system.wii = ua.indexOf("Wii") > -1;
system.ps = /playstation/i.test(ua);

//在此检测呈现引擎、平台和设备
return {
engine : engine,
browser : browser,
system : system
};

}();

以上是关于客户端检测的主要内容,如果未能解决你的问题,请参考以下文章

--客户端检测

从头认识js-js客户端检测

客户端检测

客户端检测

第九章客户端检测

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