在 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的主要内容,如果未能解决你的问题,请参考以下文章

通过 Javascript 检测 Apple Watch(例如,用户代理)

Apple设备检测

如何實現输入字符串This is an Apple on eBay 输出 Siht si na Elppa no yAbe

Apple Watch 崩溃检测

检测何时在 Apple Watch 上点击了 SKNode

检测用户是不是退还了应用购买项目中的“消耗品”(应用购买系统中的 Apple 应用商店)