如何检查浏览器是否支持 WebAssembly?

How can I check if a browser supports WebAssembly?

随着所有新的主流浏览器都支持 WebAssembly,我如何检查当前访问我网站的浏览器是否支持它?

有几种方法可以检测 WebAssembly 的存在。基本的是在全局范围内检查 WebAssembly if 是否属于 "object" 类型,但是 "global scope" 在不同的 JavaScript 环境中(主浏览器线程)是一件棘手的事情, 工人, node.js).

这样做在技术上也是不够的,因为您可能拥有 WebAssembly 支持,但由于 CSP (and exactly what CSP disallows isn't standardized yet, work ongoing here) 而无法实际编译或实例化。

保守的检查可以如下:

const supported = (() => {
    try {
        if (typeof WebAssembly === "object"
            && typeof WebAssembly.instantiate === "function") {
            const module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00));
            if (module instanceof WebAssembly.Module)
                return new WebAssembly.Instance(module) instanceof WebAssembly.Instance;
        }
    } catch (e) {
    }
    return false;
})();

console.log(supported ? "WebAssembly is supported" : "WebAssembly is not supported");

它执行以下操作:

  • 检查 WebAssembly 在当前范围内是否可以访问。如果它不是全球性的,我们真的不在乎!
  • 看看它是否有 .instantiate 函数,我们在这里实际上没有使用它,但是当你实际实例化时你会想使用它,因为它是异步的并且可以在主线程上处理大模块或者关闭。
  • 尝试同步编译尽可能小的模块(幻数'[=15=]', 'a', 's', 'm',后跟编码为uint32的版本号1),看看我们是否得到WebAssembly.Module它。
  • 最后,尝试同步实例化该模块,并检查它是否是 WebAssembly.Instance

这有点多,但不管怎样都应该有效:

  • 代码为运行(主线程,worker,node.js)。
  • CSP 如何最终实现标准化。

(信誉不足,无法发表评论……) 如果您在较旧的浏览器上进行测试,则不支持 () => 语法,因此可以将其作为一个函数来完成:

function wasmSupported() {
    // try/catch, return false; as in JF Bastien's answer
}
    
if(wasmSupported()) { ... }