冻结 User-Agent 字符串

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费积分!

有消息称 Chrome 冻结了他们的 User-Agent 字符串(所有其他主要浏览器也都加入了)。 这意味着他们仍然拥有 User-Agent (UA) 字符串(在标头中显示,并且在 JavaScript 中可用,如 navigator.userAgent)。 通过冻结它,它在检测浏览器/平台/版本方面将随着时间的推移而变得不那么有用,尽管这样做的原因是更多地出于隐私考虑,并阻止指纹识别,而不是开发人员的担忧。

在前端世界,普遍的建议是:你不应该进行 UA 探测。 主要问题是太多网站弄错了,他们使用该信息进行的更改最终弊大于利。 避免它的普遍建议是:你应该根据你正在尝试做的事情的实际情况进行测试

你是否想测试浏览器是否支持特定功能? 那么测试该功能,而不是抽象的特定浏览器概念,该浏览器应该支持该功能。

在 JavaScript 中,有时功能非常容易测试,因为你可以测试其 API 的存在

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition);
  } else {
    console.warn("Geolocation not supported");
  }

在 CSS 中,我们有一个原生机制,通过 @supports

@supports (display: grid) {
  .main {
    display: grid;
  }
}

它通过一个 API 在 JavaScript 中公开,该 API 返回布尔值答案

CSS.supports("display: flex");

并非 Web 平台上的所有内容都这么容易测试,但通常可以不进行 UA 探测就能做到。 如果处于困境,始终值得检查Modernizr 是否有针对它的测试,这算是功能测试的黄金标准,因为很有可能它已经过实战测试,并且以你可能无法预见的方式处理了边缘情况。 如果你实际上使用该库,它会为你提供清晰的逻辑断点

if (Modernizr.requestanimationframe) {
  // supported
} else {
  // not-supported
}

如果你只是确实需要知道浏览器类型、平台和版本? 好吧,显然仍然可以通过一种名为User-Agent 客户端提示 (UA-CH) 的新方法获取这些信息。

想知道平台吗? 你可以在请求中设置一个名为 Sec-CH-Platform 的标头,理论上,你将在响应中获得该信息。 你必须主动索取它,这显然足以防止出现有问题的隐私指纹识别问题。 似乎有类似 Sec-CH-Mobile 的标头,用于移动设备,这有点奇怪。 谁来决定什么是“移动”设备? 我们应该用它做出哪些决定?

在服务器级别了解有关浏览器、平台和版本的的信息通常也是可取的(在不同情况下发送不同的代码)——与客户端一样多,但没有测试的优势。 可以推测,冻结的 UA 字符串将足够长,以便服务器端情况可以移植到使用 UA-CH。

Jon Arne Sæterås 很紧张:

在职业生涯中,我一直致力于移动网页空间,并亲眼见证了它在 15 年多的时间里不断发展,我知道许多大型和小型网站都依赖于基于 User-Agent 标头的设备检测。 从 Google 的角度来看,切换到替代的 UA-CH 可能看起来很容易,但问题是推动这项变革的团队不了解其影响

基于设备检测的功能至关重要,广泛存在,不仅仅在前端代码中。 巨大的软件系统,包括后端代码,都依赖于设备检测,以及整个基础设施堆栈。

在我的主要代码库中,我们进行了一些服务器端 UA 检测。 我们使用名为 Browser 的 Rails gem,它以一个漂亮的 API 公开 UA 衍生的信息。 我可以写

if browser.safari?

end

我们还公开了该 gem 中的客户端信息,以便它也可以在客户端使用。 只有少数前端和后端的使用实例,没有一个看起来很难以其他方式处理。

过去,将前端信息以在首頁加载时有用的方式中继回服务器有点棘手(因为 UA 不了解视窗大小等信息)。 我记得我做过一些相当花哨的操作,我加载一个骨架页面,它执行一小段 JavaScript 代码,这些代码做的事情就像测量视窗宽度和屏幕大小,然后设置一个 cookie 并强制刷新页面。 如果 cookie 存在,服务器将拥有所需的信息,并且不会在这些请求中加载骨架页面。

很棘手的东西,但然后服务器将拥有服务器端的视窗宽度信息,这对某些事情很有用,比如发送小屏幕资产(例如,不同的 HTML),否则这是不可能的。

我提到这一点是因为 UA-CH 东西不要与普通的客户端提示混淆。 我们应该能够配置我们的服务器发送一个 Accept-CH 标头,然后让我们的客户端代码将要发送回的东西列入白名单,例如

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width">

这意味着服务器可以在后续页面加载时从客户端获取有关这些事项的信息。 这是一个不错的 API,但 Firefox 和 Safari 不支持它。 我想知道,如果这两个浏览器都对 UA-CH 表现出兴趣,是因为这个冻结的 UA 字符串问题,它是否会得到提升。