为什么浏览器嗅探不是推荐的做法?

时间:2009-03-19 06:13:27

标签: javascript browser sniffing

你在整个地方听到它:使用javascript来嗅探用户代理字符串以检测浏览器版本是非常糟糕的事情。最新版本的jQuery现已弃用其$.browser对象而不是$.support。但是,如果有一个只影响IE而不影响其他浏览器的错误或问题我应该怎么做,我不确定为什么?

在我的例子中,一些jQuery代码使鼠标悬停和鼠标移动时出现工具提示并消失动画。在Internet Explorer中,它看起来很糟糕,而且很紧张,工具提示div在隐藏之前会变成一个非常大的大小,并且如果你用鼠标在一堆项目上运行鼠标它会真正杀死浏览器。我不知道IE没有“支持”我应该测试的特定功能,所以只是嗅探IE并使用不同的方法要容易得多。我可以/应该做什么呢?

7 个答案:

答案 0 :(得分:10)

因为只是嗅探用户代理(这是jquery填充$ .browser对象所做的)并没有告诉你全部真相。

在许多浏览器中可以轻松更改用户代理字符串,因此,如果您例如禁用某些似乎使用IE的IE中不起作用的功能,则可能会意外禁用来自某些未来浏览器或用户的那些功能,出于某种原因(例如,基于浏览器嗅探来解决限制),假装使用IE。

这似乎不是太大的问题,但它仍然是不良做法

是的,我也是IE嗅探器。我用

$.browser.msie && document.all

只是为了确定。

答案 1 :(得分:6)

首先要注意的是,用户代理嗅探并不仅仅意味着查看navigator.userAgent,它是一个通用术语,用于描述人们用来根据他们认为的浏览器更改行为的大量方法是

所以问题是查看用户代理字符串,问题是根据您认为的浏览器决定您的网站应该做什么。这意味着您将来不可避免地限制或破坏您的网站;例如,我见过多个阻止IE的画布演示。他们没有检查是否支持画布,他们是明确地寻找IE,如果他们看到它们说IE被破坏,这意味着即使IE最终支持画布这些网站仍然无法工作。

您应该始终尝试检测您感兴趣的功能或错误,而不是浏览器嗅探。这些测试最常见的例子是“对象检测”,例如。 document.createElement("canvas").getContext是应该如何检测画布的存在,并且将在任何浏览器中正确地拾取画布,即使当前版本不支持它。

答案 2 :(得分:4)

除了浏览器嗅探不如功能嗅探的问题之外,将navigator.userAgent作为字符串处理本身就是一种非常不可靠的浏览器嗅探方式。

如果每个浏览器都坚持使用“名称/版本”方案来识别自己,那么它可能会更好,但事实并非如此。大多数浏览器声称是“Mozilla / some.version”,无论它们是什么。而开头的那一点是字符串中唯一容易解析的部分;其余的完全没有标准化。因此脚本开始在整个字符串中搜索像“MSIE”这样的字符串子字符串。这是一场灾难。

  • 有些浏览器故意互相欺骗,包括用户代理字符串中的“MSIE”,“Gecko”和“Safari”等子字符串,当它们不是那些浏览器时,主要是为了击败构思错误的字符串嗅探器。 / p>

  • 某些浏览器允许在用户控制下欺骗整个用户代理字符串。

  • 某些浏览器变体不是。例如,IE Mobile完全不像常规IE,但“MSIE”仍然会匹配它。

  • 某些浏览器允许加载项将额外令牌写入用户代理字符串,包括任意文本。只有一个恶意附加组件的注册表更改可以使MSIE看起来像Firefox。

  • 字符串匹配本质上是不可靠的。例如,名为“CLUMSIERbrowser”的新浏览器将匹配MSIE。

答案 3 :(得分:2)

因为如果你弄错了,你可能会意外地将功能切断到支持它们的未来浏览器。

我经常发现它很有用。我知道 IE6不支持alpha透明度,因此我使用浏览器嗅探来检测IE6并隐藏/更改使用它们的元素。

同样,为了快速多次运行鼠标,请尝试HoverIntent。用户setTimeout()我相信只有当鼠标在一个元素上短暂停留一段时间时才会触发事件,从而节省了周期并避免排队事件并可能冻结浏览器。

就个人而言,我更喜欢使用浏览器版本/类型方法的jQuery。它可以用来显示基于浏览器的友好问候消息。也许jQuery因为“浏览器嗅探是邪恶的”压力而弃用它。

更新

这就是John Resig(jQuery的创建者)所说的:

  

我们正在为jQuery.browser保留   可预见的未来,但我们想要   开发人员不再使用它    - 让开发人员做到这一点的最好方法就是成为一个很好的例子   适当的发展模式。

     

要明确:包含的要点   $ .support主要是浏览器错误   具体(IE错误,无法测试   用普通物体检测) - 和   它们并不包含所有可能的内容   bug(只有十几个左右)。它的   预计其他开发者会   在中添加自己的测试点   将来

     

另外,在那次提交中我忘了降落   实际的support.js文件 - 它可以   在这里找到:   http://dev.jquery.com/browser/trunk/jquery/src/support.js?rev=5986

来源:http://www.reddit.com/r/programming/comments/7l2mr/jquery_removes_all_browser_sniffing/

另见:http://dev.jquery.com/changeset/5985

答案 4 :(得分:2)

我使用了从HTML5样板和jquery中学到的东西的组合,因此使用IE条件注释来确定IE版本,然后测试这些类的存在。因此,HTML会在顶部显示:

<!--[if lt IE 7 ]> <html class="no-js ie6" lang="en"> <![endif]-->
<!--[if IE 7 ]>    <html class="no-js ie7" lang="en"> <![endif]-->
<!--[if IE 8 ]>    <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if IE 9 ]>    <html class="no-js ie9" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html class="no-js" lang="en"> <!--<![endif]-->

然后我会继续在jquery中测试.ie6,.ie7等的存在,如下所示:

if($('.ie6, .ie7').length > 0){
    // your conditional stuff here
}

适合我。

注意:显然这仅针对IE版本进行测试,但大多数其他浏览器不会导致IE最近出现的问题,而且比测试用户代理更安全!

答案 5 :(得分:0)

不建议这样做,因为浏览器谎言他们是谁。请参阅http://farukat.es/journal/2011/02/499-lest-we-forget-or-how-i-learned-whats-so-bad-about-browser-sniffing(modernizr库作者的文章)。

此外,它本质上不具备前瞻性。来自文章:

  

浏览器嗅探是一种您可以进行假设的技术   一段代码将来如何运作。通常这意味着   假设特定的浏览器错误将始终存在    - 当浏览器进行更改并修复错误时,这经常导致代码中断。

建议使用特征检测,因为它更简单,可以使代码更清晰,并且完全避免了浏览器存在的问题。

答案 6 :(得分:0)

嗅探功能,而不是使用者。伪代码:

if (browser.supports('feature')){
    //execute feature
}

else{
    //fallback
}