更改的部分信息如下:
IE8 on Windows Vista (Compatibility View) Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0) IE8 on Windows Vista Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)
除了 IE8 因 Compatibility View 功能造成单浏览器“原生”多个 User-agent 外,还有个情况也变得非常的有趣,就是几乎每个浏览器都将自己渲染引擎的标识加入到了 User-agent 中(Gecko、Webkit、Trident)。
User-agent 信息常被用作检测浏览器类型和版本的最佳途径(YUI、jQuery),而上述的改动是否意味着以后类似的检测脚本会变得更加的复杂?回答这个问题之前,让我们看下 Mootools 如何检测浏览器信息
var Browser = { Engine: {name: 'unknown', version: 0}, Features: { xpath: !!(document.evaluate), // 是否支持 XPath air: !!(window.runtime), // 是否支持 Air 扩展 query: !!(document.querySelector) // 是否支持 CSS 选择器 }, Engines: { // 判断 Opera presto: function() { return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }, // 判断 IE,根据 ActiveX 和 特有的 XMLHttpRequest 对象 trident: function() { return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? 5 : 4); }, // Webkit 核心的浏览器,如 Safari 和 Chrome webkit: function() { return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419); }, // Mozilla Gecko 核心浏览器,如 Firefox gecko: function() { return (document.getBoxObjectFor == undefined) ? false : ((document.getElementsByClassName) ? 19 : 18); } } }; Browser.detect = function() { for (var engine in this.Engines){ var version = this.Engines[engine](); // 如果具有特定的浏览器对象 if (version){ this.Engine = {name: engine, version: version}; this.Engine[engine] = this.Engine[engine + version] = true; break; } } return {name: engine, version: version}; }; Browser.detect();
上述代码让人感到耳目一新,它是根据浏览器功能而非 User-agent 判断浏览器类型。仔细考虑一下,User-agent 信息可以被伪造,同时浏览器厂商日后也会更改 User-agent 信息,所以此种情况下根据功能判断浏览器类型会可靠得多。
延伸下此策略,比如我们会编写这样的代码:
if (ie) { // ie only } else { // other browsers }
这样因浏览器差异而编写的“硬代码”,往往会造成维护两套实际相同功能的代码,并造成逻辑上的混乱。何不先抛开浏览器兼容的问题,然后再判断相应的对象是否被浏览器支持。
OK,有关编程思想的问题就不继续了…
-- Split --
PS,目前判断是否是 IE8 可这样编写
var isIE8 = !!window.XDomainRequest;