网景浏览器的 user-agent 字符串以下:windows
Mozilla/2.0 (Win95; I)浏览器
Internet Explorer 浏览器的 user-agent 字符串以下:安全
Mozilla/2.0 (cmopatible; MSIE 3.0; windows 95)服务器
这使得新生浏览器部分复制现有浏览器用户代理字符串成了一种趋势。dom
服务器能够获取到浏览器的 user-agent 字符串,客户端经过 JavaScript 的 navigator.userAgent 也能够获取。函数
// 很差的作法 if (navigator.userAgent.indexOf("MSIE") > -1) { // 是 IE } else { // 不是 IE }
解析 user-agent 字符串并不是易事,因为浏览器为了确保其兼容性,都会复制另外一个浏览器的用户代理字符串,所以随着每个新浏览器的出现,用于用户代理检测的代码都须要更新。整个方法长期而言并不具有很好的可维护性。工具
选择使用用户代理检测,最安全的方法是只检测旧的浏览器。测试
if (isInternetExplorer8OrEarlier) { // 处理 IE8 及更早版本 } else { // 处理其余浏览器 }
几乎全部的浏览器的 user-agent 均可以被工具修改,所以要尽量避免检测 user-agent。spa
2. 特性检测 代理
特性检测的原理是为特定浏览器的特性进行测试,并仅当特性存在时便可应用特性检测。
// 很差的写法 if (navigator.userAgent.indexOf("MSIE 7") > -1) { // 作些什么 } // 好的写法 if (document.getElementById) { // 作些什么 }
// 好的写法 function getById(id) { var element = null; if (document.getElementById) { // DOM element = document.getElementById(id); } else if (document.all) { // IE element = document.all[id]; } else if (document.layers) { // Netscape <= 4 element = document.layers[id]; } return element; }
这么使用特性检测是正确和恰当的,由于代码对特性作检测,当特性存在时才使用。
正确检测的顺序:
探测标准的方法
探测不一样浏览器的特定方法
均不存在时提供一个合乎逻辑的备用方法
特性推断尝试使用多个特性但仅验证了其中之一。根据一个特性的存在推断另外一个特性是否存在。问题是,推断是假设并不是事实,并且可能会致使维护性的问题。
// 很差的写法 - 特性推断 function getById(id) { var element = null; if (document.getElementByTagName) { // DOM element = document.getElementById(id); } else if (window.ActiveXObject) { // IE element = document.all[id]; } else { // Netscape <= 4 element = document.layers[id]; } return element; }
该函数是最糟糕的特性推断。
// 很差的写法 if (document.all) { // IE id = document.uniqueID; } else { id = Math.random(); }
所作的全部探测仅仅说明 document.all 是否存在,而并不能用于判断浏览器是不是 IE。document.all 的存在并不意味着 document.uniqueID 也是可用的。所以这是一个错误的隐式推断,可能会致使代码不能正常运行。
经过特性检测而推断出是某个浏览器一样是很糟糕的作法,这叫作浏览器推断,是一种错误的实践。
特性推断和浏览器推断都是糟糕的作法,应当不惜一切代价避免使用。纯粹的特性检测是一种很好的作法。不要试图推断特性间的关系,不然最终获得的结果也是不可靠的。
若是想要使用用户代理嗅探,记住这一点:这么作惟一安全的方式是针对旧的或特定版本的浏览器。而毫不应当针对最新版本或者将来的浏览器。