探索web端获取硬件信息-感叹前端命运之多艰

发布于:2024-05-09 ⋅ 阅读:(35) ⋅ 点赞:(0)

48e2422afaa043129d28f0253ae93c86_1039286376.png

背景

最近在实践一个技术推动的需求,需要获取客户端的内存和显存信息。

安全上下文

概念

安全上下文是window与worker中满足最低标准的身份验证和机密性的概念,说人话就是满足安全上下文才能用worker。 它出现是为了防止中间人攻击。 那什么情况下才满足上下文安全?必须是通过https或者wss协议提供服务才满足。 如果页面被http访问的父级页面嵌套(通过iframe加载),那也不满足安全上下文。

为什么上来先介绍这个,因为js检测硬件的接口必须在满足安全上下文的前提下才能运行

代码示例

if (window.isSecureContext) {
  // 页面在安全上下文中,所以 service worker 可用
  navigator.serviceWorker.register("/offline-worker.js").then(() => {
    // …
  });
}

示例代码兼容性

Chrome Edge Safari Firefox Chrome for Android Safari on iOS Android Browse
47+ 15+ 11.1+ 49+ 124+ 11.3+ 124+

获取设备内存

navigator.deviceMemory

navigator.deviceMemory返回大概的设备内存容量,为了防止指纹识别,所以给的值不精确,它会向下取最接近2的幂,比如实际是3g,给的值是2g;实际是6g,给的值是4g。官方给的预设值的范围是0.25、0.5、1、2、4、8等,所以需要精确控制的不能对它指望太高。

示例

if (navigator.deviceMemory) {
    console.log(`这个设备至少有${navigator.deviceMemory}gb内存`);
}

示例代码兼容性

兼容性情况也不容乐观
Chrome Edge Safari Firefox Chrome for Android Safari on iOS Android Browse
63+ 79+ 不支持 不支持 124 不支持 124

显存

思路-获取硬件信息

一开始的思路是获取显卡型号,然后得到显存的,但是发现浏览器对网页实在太不信任了(表示理解),只有Linux平台的Firefox可以获取相对正确的信息,其他浏览器都对js进行了屏蔽。

示例代码

现在已经不推荐这种方式了,但是也没有更好的办法。

const canvas = document.createElement("canvas");
const gl = canvas.getContext("experimental-webgl");
const debugInfo = gl.getExtension("WEBGL_debug_renderer_info");
gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);

示例代码兼容性

浏览器输出见下表,chrome直接给出了一个抽象值,Firefox在ubuntu下给出了正确值,但是在window系统下给出了GTX980,但测试的同事装的也是GTX1660Ti,所以就没有继续测试更多了。
浏览器 Chrome Firefox
打印信息 'Google Inc. (NVIDIA Corporation)' 'GeForce GTX 1660 Ti/PCIe/SSE2'

思路-探测一下支持的显存大小

显然上面的思路走不通了,只能尝试其他方法,本来就是想获取显存,那我就直接去试试可以用多大显存空间就可以,输入一个想要的存储大小,不报错就行,继续运行后面的代码,这里写一下webgpu官方案例。

示例

const checkGraphMemory = async (number) => {
    const adapter = await navigator.gpu.requestAdapter();
    const device = await adapter.requestDevice();
    device.pushErrorScope('out-of-memory');
    const buffer = device.createBuffer({
        size: number,
        usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_WRITE
    });
    device.popErrorScope().then(error => {
        if (error) {
            buffer = null;
            console.log(`out of memory, ${error.message}`);
        }
    });
}

WebGPU兼容性

Chrome Edge Safari Firefox Chrome for Android Safari on iOS Android Browse
113+ 113+ 不支持 不支持 不支持 不支持 不支持

集思广益

这篇文字是抛砖引玉,期望有相关经验的大佬可以在评论区指点一二。

感叹前端不易

想在网页端和硬件打交道确实不容易,很多时候都是内心祈祷着去查资料,希望浏览器厂商可以给条活路,让我实现这个功能,但是经过我调研下来发现情况并不乐观。
再次感叹一下,前端其实并不简单,当我们想像客户端和后端一样获取系统信息时非常费劲,后端发现资源不够时可以去申请预算,客户端可以摆出安装的硬件要求,只有前端只能用有限的条件去满足一个个可怕的需求,完成不了就是能力不行。