16

你到处都能听到:使用 javascript 来嗅探用户代理字符串以检测浏览器版本是一件非常糟糕的事情。最新版本的 jQuery 现在已经弃用了它的$.browser对象来代替$.support. 但是,如果存在只影响 IE 而不会影响其他浏览器的错误或问题,我该怎么办,我不知道为什么?

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

4

7 回答 7

10

因为仅仅嗅探用户代理(这是 jquery 填充 $.browser 对象所做的)并不能告诉您全部真相。

用户代理字符串可以在许多浏览器中轻松更改,因此,例如,如果您对似乎正在使用 IE的每个人禁用某些在 IE 中不起作用的功能,您可能会意外禁用某些未来浏览器或刚刚使用 IE 的用户的这些功能,出于某种原因(例如,为了绕过基于浏览器嗅探的限制),假装使用 IE。

这似乎不是什么大问题,但它仍然是不好的做法

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

$.browser.msie && document.all

只是要确定。

于 2009-03-19T06:33:21.047 回答
6

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

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

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

于 2009-03-19T07:30:11.910 回答
4

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

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

  • 一些浏览器故意互相欺骗,包括诸如“MSIE”、“Gecko”和“Safari”之类的子字符串在它们的用户代理字符串中而不是那些浏览器,主要是为了击败考虑不周的字符串嗅探器。

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

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

  • 一些浏览器允许附加组件向用户代理字符串写入额外的标记,包括任意文本。恶意插件只需更改一次注册表即可使 MSIE 看起来像 Firefox。

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

于 2009-03-19T07:16:50.240 回答
2

不建议这样做,因为浏览器会谎报自己的身份。见http://farukat.es/journal/2011/02/499-lest-we-forget-or-how-i-learned-whats-so-bad-about-browser-sniffing(作者的一篇文章现代图书馆)。

此外,它本质上不是面向未来的。来自文章:

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

推荐使用特征检测,因为它更简单,代码中的意图更清晰,并且完全避免了浏览器谎报身份的问题。

于 2013-08-14T14:36:18.033 回答
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 现在总是出现的问题,而且它比测试用户代理更安全!

于 2012-01-19T14:26:14.010 回答
2

因为如果你弄错了,你可能会不小心切断未来支持它们的浏览器的功能。

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

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

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

更新

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

在可预见的未来,我们会保留 jQuery.browser,但我们希望开发人员不再使用它——让开发人员这样做的最好方法是成为正确开发模式的好例子。

需要明确的是:$.support 中包含的要点主要是特定于浏览器的错误(无法使用普通对象检测进行测试的 IE 错误)-它们并不包含所有可能的错误(大约只有十几个)。预计其他开发人员将来会添加自己的测试点。

此外,在那次提交中,我忘记登陆实际的 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

于 2009-03-19T06:19:16.090 回答
1

嗅探功能,而不是用户代理。伪代码:

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

else{
    //fallback
}
于 2013-11-12T20:12:46.293 回答