为什么不推荐使用浏览器嗅探?

发布于 2024-07-15 11:38:35 字数 403 浏览 9 评论 0 原文

你到处都会听到这样的说法:使用 javascript 嗅探用户代理字符串来检测浏览器版本是一件非常糟糕的事情。 最新版本的 jQuery 现已弃用其 $.browser 对象来代替 $.support。 但是,如果出现仅影响 IE 而不会影响其他浏览器的错误或问题,并且我不确定原因,我该怎么办?

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

You hear it all over the place: using javascript to sniff the user agent string to detect browser versions is a Very Bad Thing. The latest version of jQuery has now deprecated its $.browser object in place of $.support. But what should I do if there's a bug or problem which is only affecting IE and not the other browsers, and I'm not sure why?

In my case, some jQuery code makes a tooltip appear and disappear with an animation on mouseover and mouseout. In Internet Explorer, it looks awful, and jittery, with the tooltip div changing to a really large size before hiding, and if you run your mouse over a heap of items with the tip it really kills the browser. I have no idea what particular feature IE doesn't "support" that I should be testing against, so it's much easier to just sniff for IE and use a different method. What could/should I do instead?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

泪痕残 2024-07-22 11:38:36

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

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

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

是的,我也是 IE 嗅探者。 我使用

$.browser.msie && document.all

只是为了确定。

Because just sniffing the user agent (which is what jquery does to populate the $.browser object) doesn't tell you the whole truth.

The user agent string can be easily changed in many browsers, so if you for example disable some features that don't work in IE from everybody who seems to be using IE, you might accidentally disable those features from some future browsers or users who just, for some reason (like for example to get around limitations based on browser sniffing), pretend to be using IE.

This might not seem too big of a problem, but it is still bad practice.

And yes, I am a IE sniffer too. I use

$.browser.msie && document.all

just to be sure.

柠檬心 2024-07-22 11:38:36

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

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

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

This first thing to note is that user agent sniffing does not just mean looking at navigator.userAgent, it is a general term to describe the large array of methods that people use to change behaviour based on what they believe the browser is.

So the problem is not looking at the user agent string, the problem is deciding what your site should do based on what you think the browser is. This means you may unavoidably limit or break your site in the future; For instance I have seen multiple canvas demos which block IE. They aren't checking to see whether canvas is supported, they are explicitly looking for IE, and if they see it they say IE is broken, this means that even if IE did eventually support canvas these sites still wouldn't work.

Rather than browser sniffing you should always attempt to detect the feature or bug you are interested in. The most common example of these tests is "object detection", eg. document.createElement("canvas").getContext is how the existence of canvas should be detected, and will correctly pick up canvas in any browser, even if current versions don't support it.

莳間冲淡了誓言ζ 2024-07-22 11:38:36

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

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

  • 一些浏览器故意互相欺骗,包括在用户代理字符串中包含“MSIE”、“Gecko”和“Safari”等子字符串(当它们不是这些浏览器时),主要是为了击败考虑不周的字符串嗅探器。

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

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

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

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

As well as the issues about browser-sniffing being inferior to capability-sniffing, handling navigator.userAgent as a string is in itself a very unreliable way of browser-sniffing.

It might work better if every browser stuck to the “Name/version” scheme of identifying themselves, but they don't. Most browsers claim to be “Mozilla/some.version” regardless of what they are. And that bit at the start is the only readily parsable part of the string; the rest is completely unstandardised. So scripts started searching the whole string for characterists substrings like “MSIE”. This is a disaster.

  • Some browsers deliberately spoof each other, including substrings like “MSIE”, “Gecko” and “Safari” in their user agent strings when they're not those browsers, mostly to defeat ill-conceived string sniffers.

  • Some browsers allow the entire user agent string to be spoofed under user control.

  • Some browser variants aren't. For example IE Mobile is nothing at all like regular IE, but “MSIE” will still match it.

  • Some browsers allow add-ons to write extra tokens to the user agent string including arbitrary text. Just one registry change by a rogue add-on can make MSIE look like Firefox.

  • String matching is just inherently unreliable. For example a new browser called “CLUMSIERbrowser” would match MSIE.

神魇的王 2024-07-22 11:38:36

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

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

另外,如果要多次快速移动鼠标,请尝试 HoverIntent。 我相信它的用户 setTimeout() 只会在鼠标短暂停留在某个元素上时触发事件,从而节省周期并避免事件排队并可能冻结浏览器。

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

更新

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

我们保留 jQuery.browser
可预见的未来,但我们希望
开发人员不再使用它
- 让开发人员做到这一点的最好方法就是成为一个好榜样
正确的发展模式。

需要明确的是:其中包含的要点
$.support 主要是浏览器错误
特定的(无法测试的 IE bug
与正常的物体检测) - 和
它们并没有涵盖所有可能的情况
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

Because if you get it wrong, you may accidentally cut off features to future browsers that support them.

I often find it useful. I know IE6 doesn't support alpha transparency, so I use browser sniffing to detect IE6 and hide/change elements that use them.

Also for running the mouse over quickly numerous times, try HoverIntent. It users setTimeout() I believe to only fire events when the mouse has been over an element for a brief period of time, saving cycles and avoiding queuing up of events and potentially freezing the browser.

Personally, I preferred jQuery with the browser version/type methods. It could be used to show a friendly hello message based on browser. Maybe jQuery deprecated it due to pressure that 'browser sniffing is evil'.

Update

This is what John Resig (creator of jQuery) says:

We're keeping jQuery.browser for the
foreseeable future but we want
developers to move away from using it
- and the best way to get developers to do that is to become a good example
of proper development patterns.

To be clear: The points included in
$.support are mostly browser bug
specific (IE bugs that can't be tested
with normal object detection) - and
they don't encompass every possible
bug (only about a dozen or so). It's
expected that other developers will
add their own testing points in the
future.

Also, in that commit I forgot to land
the actual support.js file - it can be
found here:
http://dev.jquery.com/browser/trunk/jquery/src/support.js?rev=5986

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

Also see: http://dev.jquery.com/changeset/5985

烟─花易冷 2024-07-22 11:38:36

我结合使用了从 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 现在总是出现的问题,而且它比测试用户代理安全得多!

I use a combination of stuff I learned from the HTML5 boilerplate and jquery, so using the IE conditional comments to determine IE version, then test for the existance of these classes. Therefore the HTML would have this at the top:

<!--[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]-->

Then I would go on to test for the existance of .ie6, .ie7 etc in jquery like this:

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

Works well for me.

NOTE: Obviously this only tests for IE versions but most other browsers don't cause the issues that IE always does these days and it's much safer than testing the user agent!

债姬 2024-07-22 11:38:36

不推荐这样做,因为浏览器会谎报它们的身份。 请参阅http://farukat.es/journal/2011/02/499-lest-we-forget-or-how-i-learned-whats-so-bad-about-browser-sniffing( Modernizr 库作者的一篇文章)。

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

浏览器嗅探是一种对以下内容做出假设的技术
一段代码将来如何工作。 一般来说这意味着
假设特定的浏览器错误将始终存在
- 当浏览器进行更改和修复错误时,这经常会导致代码破坏。

建议使用功能检测,因为它更简单,可以使代码意图更清晰,并且完全避免浏览器谎报身份的问题。

It's not recommended because browsers lie about who they are. See http://farukat.es/journal/2011/02/499-lest-we-forget-or-how-i-learned-whats-so-bad-about-browser-sniffing (an article by the author of the modernizr library).

Also, it is inherently not future-proof. From the article:

Browser sniffing is a technique in which you make assumptions about
how a piece of code will work in the future. Generally this means
making an assumption that a specific browser bug will always be there
- which frequently leads to code breaking when browsers make changes and fix bugs.

Feature detection is recommended as it's much simpler, makes for clearer intent in code, and avoids the issue entirely of browsers lying about who they are.

并安 2024-07-22 11:38:36

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

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

else{
    //fallback
}

Sniff for features, not for useragents. Pseudocode:

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

else{
    //fallback
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文