在 JavaScript 中检测 Apple Silicon mac

Posted

技术标签:

【中文标题】在 JavaScript 中检测 Apple Silicon mac【英文标题】:Detecting Apple Silicon mac in JavaScript 【发布时间】:2021-03-16 16:40:38 【问题描述】:

有没有办法在 javascript 中检测 Apple Silicon Mac?navigator 中的属性似乎不是很有帮助,例如,navigator.platform 设置为 MacIntel 和用户代理完全相同。

原因部分:我有两个可用的软件版本,分别用于 Intel 和 Apple Silicon。询问用户“你的 Mac 是 Apple Silicon 还是 Intel?”不是很好。

【问题讨论】:

我不是 Mac 用户,但您不能提供“通用二进制文件”吗?这样一来,用户的 Mac 拥有什么 CPU 就无关紧要了。 有趣的是,Chrome 的下载页面确实询问用户他们拥有什么芯片(Apple 或 Intel)。不过,我认为 Chrome 的下载可能是通用二进制文件,因此可能无关紧要。 support.google.com/chrome/answer/95346(查看“Mac”,然后“检查您的 Mac 配置”) Electron 不提供通用二进制文件,动机如下:electronjs.org/blog/apple-silicon Chrome 只下载安装程序,它会检查架构,然后根据它获取实际的东西。对于简单的应用程序,这种方法有点矫枉过正。 通过 WebGL 渲染器进行检测目前仅作为 Chrome 功能运行,因为浏览器正试图避免检测到平台。我在这里为它制作了一个测试页面:browserstrangeness.github.io/detect_mac.gpu.htm 和一个镜像:browserstrangeness.bitbucket.io/detect_mac.gpu.htm(我很确定 Google 也不打算将其作为使用 Chrome 进行平台检测的方法。) 【参考方案1】:

您可以使用一个库来提供有关 Node.js 中的操作系统的信息 - os (const os = require('os'))。它有一个返回 cpu 核心的方法 - os.cpus(),你可以只取第一个元素并检查它是否是你想要的确切模型,或者它是否只是在其模型中包含“Apple M1”作为字符串 - let isM1 = cpuCore[0].model.includes("Apple M1")

您也可以检查os.arch() 方法:

返回 Node.js 所针对的操作系统 CPU 架构 二进制文件已编译。

然而,在使用 arch 方法时,我建议高度谨慎,因为我已经多次出现了 M1 Mac 从 os.arch() 返回 x64 而不是arm64 这是预期的结果。

【讨论】:

os.arch() 不返回当前的计算机体系结构 - 它返回构建应用程序的体系结构。 @astoilkov 在这种情况下,应用程序甚至意味着什么?我从字面上引用了官方文档,你为什么要使用不同的定义?在大多数情况下,您会期望 M1 处理器使用 M1 编译版本的 Node,这就是为什么我说 arm64 是预期的结果。事实上,Node.js 会被您当前的操作系统编译,以至于 process.arch 这是完全相同的功能意味着它们在文档中给出的示例中是相同的 - nodejs.org/api/process.html#process_process_arch 对不起。我应该澄清一下。我应该给出上下文而不是盲目地写评论。我正在谈论的用例是电子。当有一个 Electron 应用程序并且需要了解计算机架构时,os.arch() 给出了应用程序的架构,这取决于用户下载的应用程序的版本。【参考方案2】:

我有一个解决方案,但感觉很脆弱。

检查操作系统,因为 Apple Silicon 仅存在于 10_15 或更高版本:

navigator.userAgent.match(/OS X 10_([789]|1[01234])/)

使用 webgl 检查 GPU:

var w = document.createElement("canvas").getContext("webgl");
var d = w.getExtension('WEBGL_debug_renderer_info');
var g = d && w.getParameter(d.UNMASKED_RENDERER_WEBGL) || "";
if (g.match(/Apple/) && !g.match(/Apple GPU/)) 
   ...definitely arm...

如果您看到 Apple GPU,那么是 Safari 隐藏了 GPU 以防止指纹识别。挖掘能力:

if (w.getSupportedExtensions().indexOf("WEBGL_compressed_texture_s3tc_srgb") == -1) 
  ...probably arm...

(我将我的 MacBook Pro 的功能与新的 M1 Air 进行了比较,但 Air 上没有那个。所有其他的都是相同的。)

我正在采取的方法是给用户一个选择,但是使用这个测试来选择默认值。

如果有人有其他想法可能有助于缩小范围,如果它是 M1,我很乐意尝试......

更新:正如 Romain 在 cmets 中指出的那样,Apple 在 Big Sur 中添加了对缺少的扩展的支持,因此这现在不起作用(在 Safari 中;它仍然在 Chrome 和 Firefox 中起作用)。

【讨论】:

不错!我同意选择默认值,这可能是一个很好的测试,至少在目前,Apple Silicon 百分比正在缓慢增加。 我有 MacBookAir M1 和最新的 Safari,这个扩展不再丢失。

以上是关于在 JavaScript 中检测 Apple Silicon mac的主要内容,如果未能解决你的问题,请参考以下文章