场景:点击按钮下载什么架构的客户端

为啥需要JS判断当前浏览器所属的系统架构?可以代入到场景:如果需要自行分发arm、x86技术架构的客户端安装包(为了控制包大小等),怎么能让用户直接点击下载按钮,下载正确的技术架构,而不是需要用户了解相关内容,查看本机架构呢?

UserAgent?

大部分都建议通过UA 匹配相关信息,去判断,如下面代码展示。

navigator.userAgent
// 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'

但是这是个运行在MacOS arm架构芯片的Chrome上。

Platform?

ua不行,那再在navigator找找呢?.platform。也还是不准确。

navigator.platform
// 'MacIntel'

getHighEntropyValues

js其实在这种场景挺束手无策的,相关浏览器运行在什么架构下,自己也无法控制,甚至还有在arm架构上运行x86应用的,那到底算什么架构呢?(说的就是浓眉大眼的Rosetta)。

好在还有getHighEntropyValues 能够挣扎下。不过作为实验性接口,需要考虑兼容性。

navigator.userAgentData.getHighEntropyValues(['architecture']).then(res => console.log(res))
/*
{
    "architecture": "arm",
    "brands": [
        {
            "brand": "Google Chrome",
            "version": "125"
        },
        {
            "brand": "Chromium",
            "version": "125"
        },
        {
            "brand": "Not.A/Brand",
            "version": "24"
        }
    ],
    "mobile": false,
    "platform": "macOS"
}
*/

该接口也仅能在较新的浏览器上使用,可能会让代码多一些判断条件,但是能让部分用户体验好些,就得自己权衡了。

判断Rosetta

其实还想好奇在Rosetta环境运行的Chrome,这个接口获取的数据会是什么。折腾半天没找到专门的x86的Chrome安装包,就作罢。理应不做兼容,在Rosetta启动的进程获取的就应该会是x86。

为啥好奇这个呢,这就多啰嗦下了。

场景:客户端x86自动更新,真的是应该下载这个架构的包吗

有些客户端在一开始或有其他原因,导致可能只支持了MacOS的Intel芯片,还做了自动更新,下载地址指向对应架构的安装包(Electron)。这时候,如果支持arm芯片的时候,原先通过Rosetta启动的用户,就没法很好的更新到合适的架构上来了。

虽然如此,但是也没有系统也没有给出判断的办法,只能通过些曲线救国的方案了,通过调用终端指令了。

sysctl sysctl.proc_translated

sysctl 是一个在 Unix-like 系统上用来读取和设置系统内核参数的命令行工具。sysctl.proc_translated 是一个特定的内核参数,用于指示当前正在运行的进程是否是通过 Rosetta 翻译运行的。

  • 当前进程如果是原生 ARM 架构的,这个值会是 0。
  • 如果当前进程是通过 Rosetta 翻译的,这个值会是非 0。

最后

今天分享JS的小函数,给出了使用的场景,又因为做过类似的而好奇,多啰嗦了些。希望对大家有帮助/doge。