如何在没有navigator.platform的情况下确定浏览器平台

14

以前我们可以使用navigator.platform来检查浏览器运行的操作系统(这仍然对于诸如键盘事件转换,例如HomemetaKey+ArrowLeft之类的事情是必要的,或者将虚拟模态“关闭”图标放置在遵循操作系统惯例的方式),但现在该选项不再存在。(也就是说,目前从技术上讲它仍然存在,但它不再是一个可以确保在部署代码时起作用的解决方案)。

我似乎找不到任何关于如果需要操作系统知识应该使用什么替代方法的官方文档:新的和改进的方式是什么,以确定网页正在运行的操作系统/平台?

(当前最流行的SO问题,“使用JavaScript或jQuery检测Mac OS X或Windows计算机的最佳方法”,自从决定弃用navigator.platform后还没有任何编辑过答案,因此目前不是有用的)

2个回答

2
一种选择是使用 navigator.userAgentData 以及 .getHighEntropyValues() 方法。然后,我们可以利用 User-Agent Client Hints API 并从 userAgentData 请求多个提示来获取高熵值。提供了一种从 User-Agent 信息中检测操作系统的方法,因为 navigator.platform 已不再可用。
或者,只需访问 navigator.userAgent,它具有完全支持并为当前浏览器提供用户代理字符串,其中可以提取操作系统。

function checkOS(n) {
  if (n.userAgentData) {
    const hints = ["architecture", "model", "platform", "platformVersion", "uaFullVersion"];
    n.userAgentData.getHighEntropyValues(hints)
      .then(ua => {
        console.log(ua);
      });
  } else {
    console.log(n.userAgent);
    return "navigator.userAgentData is not supported!";
  }
}

checkOS(navigator);

这是我在DevTools“问题”选项卡中找到的唯一文档,除了update on user agent string reduction的信息。

页面或脚本正在访问至少一个 navigator.userAgentnavigator.appVersionnavigator.platform。在 Chrome 的未来版本中,用户代理字符串中可用的信息量将会减少。- 要解决此问题,请使用特性检测、渐进增强或迁移到 navigator.userAgentData 替换对 navigator.userAgentnavigator.appVersionnavigator.platform 的使用。

我尝试在Windows和macOS机器上使用Chrome将 navigator.userAgentData 记录到控制台,以查看它包含的数据类型,该对象确实具有一些有用的信息,特别是 getHighEntropyValues() 方法。

// NavigatorUAData {brands: Array(3), mobile: true}
{
  "brands": [
    {
      "brand": "Chromium",
      "version": "92"
    },
    {
      "brand": " Not A;Brand",
      "version": "99"
    },
    {
      "brand": "Google Chrome",
      "version": "92"
    }
  ],
  "mobile": false,
  "getHighEntropyValues": function getHighEntropyValues() { [native code] }
}

浏览器支持navigator.userAgentData并不是很好(只有Chrome、Edge和Opera支持),但这可能是从userAgentData检测操作系统的正确方向,因为navigator.platform已经不再可用。CodePen演示


6
是的,这似乎又是一个只针对Chrome浏览器的解决方案,而不是真正达成一致的替代方案=( - Mike 'Pomax' Kamermans
1
是的,同意 =( - Tanner Dolby

1

事实证明,目前唯一现实的选择是查看用户代理字符串,并根据此做出决策(手动编写代码或使用用户代理解析库来完成)。

虽然这并不理想,但由于目标是操作系统检测,而明确不是浏览器检测,因此这也不会太过于hacky或容易在未来出现问题。


我正在编写集成测试,因此没有HTTP请求。现在我该怎么办? - canbax
我有点困惑,你如何编写集成测试(即使用浏览器加载页面并与之交互,基于整个系统执行测试,而不是单元测试),而又没有任何请求页面来运行它们的测试操作? - Mike 'Pomax' Kamermans
实际上有一些 HTTP 请求,但我们只是返回模拟响应。所以没有后端。 - canbax
还有一点困惑:是什么阻止浏览器检查自己的用户代理? - Mike 'Pomax' Kamermans
嗯,我不确定,也许可以做到。可以进行HTTP调用并提供模拟响应,然后检查userAgent吗?我只是使用了process.platform - canbax
浏览器中没有process,因此您根本不在运行基于浏览器的集成测试(例如selenium、playwright等)。您正在进行某些操作,并且这些操作是在Node中完成的,但目前我们只知道这些。您可以使用process.platform询问Node当前正在运行的操作系统,但如果您甚至都没有使用浏览器,则只需为测试所假装运行的任何操作系统模拟用户代理即可。 - Mike 'Pomax' Kamermans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接