【问题标题】:Not possible to test WebAssembly page locally with Firefox - SharedArrayBuffer not defined无法使用 Firefox 在本地测试 WebAssembly 页面 - 未定义 SharedArrayBuffer
【发布时间】:2021-07-13 08:10:45
【问题描述】:

我正在使用基于 WebAssembly 的软件,该软件使用需要 SharedArrayBuffer 的多线程。它在 Chromium local/deployed 和 Firefox 89 部署中运行良好,但由于最好的性能是在 Firefox 下,我想在我的机器上测试和调整它,所以我运行python -m SimpleHTTPServer。在这种情况下,当我在 Firefox 中打开 127.0.0.1:8000 或 0.0.0.0:8000 时,SharedArrayBufferundefined。也许这是一个安全设置,但是当使用 localhost 时,我真的对 Firefox 对这种情况的解释不感兴趣——这应该只是运行。我怎样才能让它工作?我需要不同的网络服务器、不同的设置吗?

【问题讨论】:

  • 您可能缺少必要的 HTTP 标头:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • @CherryDT 知道如何使用 simplehttpserver 或 nginx 设置它们吗?
  • 我想到了一个更简单的方法,因为听起来你无论如何都不会通过postMessage 传递对象 - 请参阅我的答案

标签: firefox webassembly httpserver sharedarraybuffer


【解决方案1】:

正如您猜对的,它与安全限制有关。关于SharedArrayBuffer 的使用已经发生了变化,这些变化已经在 Firefox 79 中实现,并且很快也会在 Chrome 中出现(从 Chrome 92 开始)。 (撰写本文时间:2021 年 7 月 13 日。)

主要目的是限制SharedArrayBuffers在postMessage中的使用。除非设置了某些限制性 COOP/COEP 标头以防止跨域攻击,否则任何此类尝试都会引发错误:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

不幸的是,没有这些标头,也就没有全局SharedArrayBuffer 构造函数。显然,这种限制将来可能会取消。虽然对象本身仍然有效(仅通过postMessage 传递它们才会抛出),但您需要一种不同的方式来实例化它们。您可以改用WebAssembly.Memory

const memory = new WebAssembly.Memory({ initial: 10, maximum: 100, shared: true })
// memory.buffer is instanceof SharedMemoryBuffer

您现在可以更进一步并从中恢复构造函数。因此,使用以下代码作为“shim”,您现有的代码应该可以工作,只要它不尝试通过postMessage 传递缓冲区:

if (typeof SharedArrayBuffer === 'undefined') {
  const dummyMemory = new WebAssembly.Memory({ initial: 0, maximum: 0, shared: true })
  globalThis.SharedArrayBuffer = dummyMemory.buffer.constructor
}

// Now, `new SharedArrayBuffer(1024)` works again

进一步阅读:

【讨论】:

    【解决方案2】:

    正如@CherryDT 在评论中指出的那样,问题是缺少本地服务器的标头。上网一搜,有a blog 介绍了在Firefox 中使用python web 服务器开发WebAssembly 的过程。而不是python -m SimpleHTTPServer,必须添加一个包含此内容的文件./wasm-server.py(对于Python 2):

    # Python 2
    
    import SimpleHTTPServer
    import SocketServer
    
    class WasmHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
        def end_headers(self):        
            self.send_header("Cross-Origin-Opener-Policy", "same-origin")
            self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
            SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)
    
    
    # Python 3.7.5 adds in the WebAssembly Media Type. Version 2.x doesn't
    # have this so add it in.
    WasmHandler.extensions_map['.wasm'] = 'application/wasm'
    
    
    if __name__ == '__main__':
        PORT = 8080
        httpd = SocketServer.TCPServer(("", PORT), WasmHandler)
        print("Listening on port {}. Press Ctrl+C to stop.".format(PORT))
        httpd.serve_forever()
    

    那么就可以在127.0.0.1:8080测试应用程序了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-16
      • 1970-01-01
      • 2019-05-06
      • 1970-01-01
      • 2015-06-14
      • 1970-01-01
      相关资源
      最近更新 更多