9.客户端检测
9.1 能力检测
最常用也最为人们广泛接受的客户端检测形式是能力检测(又称特性检测)。能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力。
if (object.propertyInQuestion){
//使用 object.propertyInQuestion
}
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");
}
}
9.1.1 更可靠的能力检测
能力检测对于想知道某个特性是否会按照适当方式行事(而不仅仅是某个特性存在)非常有用
//不要这样做!这不是能力检测——只检测了是否存在相应的方法
function isSortable(object){
return !!object.sort;
}
//这样更好:检查 sort 是不是函数
function isSortable(object){
return typeof object.sort == "function";
}
//在 IE8 及之前版本中不行
function hasCreateElement(){
//typeof document.createElement 返回的是"object",而不是"function"。
return typeof document.createElement == "function";
//IE9 纠正了这个问题,对所有 DOM 方法都返回"function"。
}
在浏览器环境下测试任何对象的某个特性是否存在,要使用下面这个函数
//作者: Peter Michaux
function isHostMethod(object, property) {
var t = typeof object[property];
return t=='function' ||
(!!(t=='object' && object[property])) ||
t=='unknown';
}
result = isHostMethod(xhr, "open"); //true
result = isHostMethod(xhr, "foo"); //false
9.1.2 能力不是浏览器检测
一次性检测所有相关特性,而不要分别检测
//确定浏览器是否支持 Netscape 风格的插件
var hasNSPlugins = !!(navigator.plugins && navigator.plugins.length);
//确定浏览器是否具有 DOM1 级规定的能力
var hasDOM1 = !!(document.getElementById && document.createElement &&
document.getElementsByTagName);
9.2 怪癖检测
怪癖检测( quirks detection)的目标是识别浏览器的特殊行为。
var hasDontEnumQuirk = function(){
var o = { toString : function(){} };
for (var prop in o){
if (prop == "toString"){
return false;
}
}
return true;
}();
var hasEnumShadowsQuirk = function(){
var o = { toString : function(){} };
var count = 0;
for (var prop in o){
if (prop == "toString"){
count++;
}
}
return (count > 1);
}();
9.3 怪癖检测
用户代理检测通过检测用户代字符串来确定实际使用的浏览器。 在每一次 HTTP 请求过程中,用户代理字符串是作为响应首部发送的,
而且该字符串可以通过 JavaScript 的 navigator.userAgent 属性访问。在服务器端,通过检测用户代理字符串来确定用户使用的浏览器是一种常用而且广为接受的做法。
9.3.1 UA历史
- 第一款浏览器 1993 Mosaic/0.9 美国 NCSA( National Center for Supercomputing Applications,国家超级计算机中心)
- Mozilla (Mosaic Killer) Mozilla/版本号 [语言] (平台; 加密类型)
- 语言:即语言代码,表示应用程序针对哪种语言设计。
- 平台:即操作系统和(或)平台,表示应用程序的运行环境。
- 加密类型:即安全加密的类型。可能的值有 U( 128 位加密)、 I( 40 位加密)和 N(未加密)。
- Netscape Navigator 和 Internet Explorer 3 1996年
- Mozilla/版本号 (平台; 加密类型 [; 操作系统或 CPU 说明])
- Mozilla/2.0 (compatible; MSIE 3.02; Windows 95) IE3.02
- Netscape Communicator 4 和 IE4~IE8
- Mozilla/版本号 (平台; 加密类型 [; 操作系统或 CPU 说明])
- Mozilla/4.79 (Win98; I)
- Mozilla/4.0 (compatible; MSIE 版本号; 操作系统)
- Mozilla/4.0 (compatible; MSIE 版本号; 操作系统; Trident/Trident 版本号) //IE8
- Gecko
Gecko 是 Firefox 的呈现引擎。当初的 Gecko 是作为通用 Mozilla 浏览器的一部分开发的,而第一个采用 Gecko 引擎的浏览器是 Netscape 6- Mozilla/Mozilla 版本号 (平台; 加密类型; 操作系统或 CPU; 语言; 预先发行版本)
Gecko/Gecko 版本号 应用程序或产品/应用程序或产品版本号
- Mozilla/Mozilla 版本号 (平台; 加密类型; 操作系统或 CPU; 语言; 预先发行版本)
- WebKit
- 2003 年, Apple 公司宣布要发布自己的 Web 浏览器,名字定为 Safari。 Safari 的呈现引擎叫 WebKit,是 Linux 平台中 Konqueror 浏览器的呈现引擎 KHTML 的一个分支。几年后, WebKit 独立出来成为了一个开源项目,专注于呈现引擎的开发。
- Konqueror
- 与 KDE Linux 集成的 Konqueror,是一款基于 KHTML 开源呈现引擎的浏览器。尽管 Konqueror 只能在 Linux 中使用,但它也有数量可观的用户。为确保最大限度的兼容性, Konqueror 效仿 IE 选择了如下用户代理字符串格式:
Mozilla/5.0 (compatible; Konqueror/ 版本号; 操作系统或 CPU )
- 与 KDE Linux 集成的 Konqueror,是一款基于 KHTML 开源呈现引擎的浏览器。尽管 Konqueror 只能在 Linux 中使用,但它也有数量可观的用户。为确保最大限度的兼容性, Konqueror 效仿 IE 选择了如下用户代理字符串格式:
- Chrome
- 谷歌公司的 Chrome 浏览器以 WebKit 作为呈现引擎,但使用了不同的 JavaScript 引擎。
Mozilla/5.0 ( 平台; 加密类型; 操作系统或 CPU; 语言) AppleWebKit/AppleWebKit 版本号 (KHTML,like Gecko) Chrome/ Chrome 版本号 Safari/ Safari 版本
Chrome 7 的完整的用户代理字符串如下:
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML,like Gecko) Chrome/7.0.517.44 Safari/534.7
- 谷歌公司的 Chrome 浏览器以 WebKit 作为呈现引擎,但使用了不同的 JavaScript 引擎。
- Opera
- 仅就用户代理字符串而言, Opera 应该是最有争议的一款浏览器了
- Opera/ 版本号 (操作系统或 CPU; 加密类型) [语言]
Windows XP 中的 Opera 7.54 会显示下面的用户代理字符串: - Opera/7.54 (Windows NT 5.1; U) [en]
9.3.2 UA检测技术
if (ieVer >=6){
//代码
}
- 1.识别呈现引擎
var clent = function(){
var engine ={
呈现引擎
ie: 0,
gecko: 0,
webkit: 0,
khtml: 0,
opera: 0,
//具体的版本号
ver: null
};
//呈现平台、引擎、设备
return {
engine:engine
};
}();
if(client.engine.ie){
//针对IE的代码、
}else if(client.engine.gecko>1.5){
if(client.engine.ver=='1.8.1'){
//针对这个版本执行某些操作
}
}
- 识别Opera
if(window.opera){
engine.ver = window.opera.version();
engine.opera = parseFloat(engine.ver);
}
- 识别WebKit
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);
}
- 识别Gecko
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)) {
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);
}
9.4 小结
- 能力检测-在编写代码之前先检测特定浏览器的能力
- 怪癖检测-浏览器的
- 用户代理检测-通过检测用户代理字符串来识别浏览器