有没有办法在JavaScript中检测Apple Silicon的Mac?
navigator
中的属性似乎不是很有用,例如navigator.platform
被设置为MacIntel
并且用户代理完全相同。
为什么要这样做:我有两个版本的软件可用,一个用于英特尔处理器,另一个用于Apple Silicon。询问用户“你的Mac是Apple Silicon还是英特尔?”并不是很好的方法。
有没有办法在JavaScript中检测Apple Silicon的Mac?
navigator
中的属性似乎不是很有用,例如navigator.platform
被设置为MacIntel
并且用户代理完全相同。
为什么要这样做:我有两个版本的软件可用,一个用于英特尔处理器,另一个用于Apple Silicon。询问用户“你的Mac是Apple Silicon还是英特尔?”并不是很好的方法。
我有一个解决方案,但感觉相当脆弱。
检查操作系统,因为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...
}
如果您看到苹果GPU,则是Safari隐藏了GPU以防止指纹识别。深入了解其能力:
if (w.getSupportedExtensions().indexOf("WEBGL_compressed_texture_s3tc_srgb") == -1) {
...probably arm...
}
(我将我的MacBook Pro的性能与新款M1 Air进行了比较,但是Air上缺少了那个。其他所有功能都相同。)
我的做法是给用户选择,但使用此测试来选择默认选项。
如果有人有另一个想法可以帮助缩小范围以确定是否为M1,我很乐意尝试……
更新:正如Romain在评论中指出的那样,苹果在Big Sur中添加了对缺失扩展的支持,因此现在无法使用此方法(在Safari中无法使用;仍可在Chrome和Firefox中使用)。
现在可以通过navigator.userAgentData
实现,尽管并非每个浏览器都支持。
await navigator.userAgentData.getHighEntropyValues(['architecture'])
{
architecture: "arm"
brands: [{…}, {…}, {…}],
mobile: false,
platform: "macOS"
}
https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues
有一个可以使用的库,它提供有关 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
的情况。
编辑:最好将 cpuCore[0].model.includes("Apple M1")
替换为正则表达式或 cpuCore[0].model.includes("Apple")
,因为早期版本的 M1 Mac 在型号下返回“Apple 处理器”。
os.arch()
不会返回当前计算机体系结构,而是返回应用程序构建的体系结构。 - astoilkovprocess.arch
这个完全相同的函数在文档中给出的示例中暗示它们是相同的。- https://nodejs.org/api/process.html#process_process_arch - InsertKnowledgeos.arch()
会给出应用程序的架构,这取决于用户下载的应用程序版本。 - astoilkovos.arch
的问题在这里描述:https://github.com/nodejs/node/issues/41900#issuecomment-1113511254 - loretoparisi