浏览器检测与特征检测

IT技术 javascript html dom cross-browser
2021-01-24 05:50:06

我要扮演一个代言人的角色。我一直想知道为什么浏览器检测(而不是特征检测)被认为是一种糟糕的做法。如果我测试某个浏览器的某个版本并确认,某些功能的行为是以某种可预测的方式,那么决定做特殊情况似乎是可以的。理由是将来会万无一失,因为这部分浏览器版本不会改变。另一方面,如果我检测到一个 DOM 元素有一个函数 X,它并不一定意味着:

  1. 此功能在所有浏览器中的工作方式相同,并且
  2. 更重要的是,即使在未来的所有浏览器中,它也会以相同的方式工作。

我刚刚查看了 jQuery 源代码,他们通过将精心构建的 HTML 片段插入 DOM 来进行功能检测,然后他们检查某些功能。这是一种明智而可靠的方式,但我会说,如果我只是在我的个人 JavaScript 小片段(没有 jQuery)中做这样的事情,那就有点太重了。他们还拥有几乎无限的 QA 资源的优势。另一方面,你经常看到人们做的是他们检查函数 X 的存在,然后基于此,他们假设该函数在所有具有此函数的浏览器中都会以某种方式运行。

我并不是说特征检测不是一件好事(如果使用得当),但我想知道为什么浏览器检测通常会立即被忽略,即使这听起来合乎逻辑。我想知道这是否是另一种流行的说法。

3个回答

在我看来,自从几年前 Resig发表这篇文章以来,浏览器检测一直受到广泛反对。然而,Resig 的评论特定于库/框架代码,即其他[特定领域] 应用程序/站点使用代码

我认为特征检测毫无疑问非常适合库/框架但是,对于特定于域的应用程序,我不太确定浏览器检测是否有那么糟糕。它适用于解决难以检测到的已知浏览器特征,或者适用于在功能本身的实现中存在错误的浏览器。浏览器检测合适的时间:

  • 不是跨浏览器的站点/应用程序,需要显示针对该客户端浏览器定制的警告/对话框/DifferentPage。这在遗留应用程序中很常见。
  • 对支持的浏览器和版本有严格政策的银行或私人网站(以避免可能危及用户数据的已知安全漏洞)
  • 微优化:在以某种方式执行某些操作时,有时一个浏览器比其他浏览器快得多。根据您的用户群,在该特定浏览器/版本上进行分支可能是有利的。
  • IE6 中缺乏 png 透明度
  • 许多仅在特定浏览器版本中出现的显示/渲染问题(阅读:IE css 支持),您实际上并不知道要测试什么功能。

也就是说,在进行浏览器检测时有一些主要的陷阱(可能是我们大多数人犯过的)需要避免。

@RobG:我从未说过“浏览器检测”等于“拒绝访问”或“放弃支持”。通过浏览器检测,我只是指if (navigator.userAgent...)代码中的存在如果检测到某个浏览器,会发生什么变化。它可能只是意味着使用 gif 而不是 png。
2021-03-11 05:50:06
在我看来,自从几年前 Resig 发表这篇文章以来,浏览器检测一直受到广泛反对”。在那篇文章之前很久,浏览器检测是不好的做法。我不认为您有任何使用浏览器检测堆栈的原因。在什么 Intranet 应用程序中缺乏对 PNG 透明度的支持,这是一个显示塞子?编写跨浏览器站点现在比以往任何时候都更简单,只要为新功能采用务实的方法,例如,您真的会因为浏览器不支持constlet 而放弃对它的支持吗?
2021-03-30 05:50:06

这是一篇很好的文章,解释了特征检测如何在许多方面优于浏览器嗅探。

事实上,嗅探是极其脆弱的。它在理论上很脆弱,因为它依赖于任意 userAgent字符串,然后实际上将该字符串映射到特定行为。正如时间所证明的那样,它在实践中也很脆弱。测试数十个浏览器的每个主要和次要版本并尝试解析其中一些版本的内部版本号根本不切实际;另一方面,针对怪癖测试某些行为要健壮得多。例如,功能测试经常会发现浏览器供应商偶然相互复制的错误和不一致之处。

根据我自己的经验,在 IE8 中修复 Prototype.js,我知道如果我们不首先嗅探,90% 的问题是可以避免的。

在修复 Prototype.js 时,我发现一些需要测试的功能实际上在 JS 库中非常常见,所以我做了一些常见功能测试的集合,供任何愿意摆脱嗅探的人使用。

理想的解决方案是结合功能和浏览器检测。前者失败是因为你提到的几点,后者是因为有时浏览器会发布虚假信息以“使事情正常进行”。

Mozilla 有一个很棒的Browser Detection Primer,可能对你也有帮助。

来自维基百科 “在其历史上的不同时期,Web 的使用一直由一种浏览器主导,以至于许多网站被设计为仅适用于该特定浏览器,而不是根据 W3C 和 IETF 等机构的标准。此类站点通常包含“浏览器嗅探”代码,它根据接收到的用户代理字符串更改发送的信息。这可能意味着不太流行的浏览器不会发送复杂的内容,即使它们可能能够正确处理它,或者在极端情况下拒绝所有内容。因此,各种浏览器“伪装”或“欺骗”该字符串,以便将自己标识为此类检测代码的其他东西;通常,浏览器的真实身份随后会包含在字符串中。