1

我正在使用基于 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 对这种情况的解释不感兴趣——这应该只是运行。我怎样才能让它工作?我需要不同的网络服务器、不同的设置吗?

4

2 回答 2

2

正如您猜对的那样,它与安全限制有关。已经在 Firefox 79 中实现了有关使用的更改,并将SharedArrayBuffer很快登陆 Chrome(从 Chrome 92 开始)。(撰写本文时间:2021 年 7 月 13 日。)

主要目的是限制SharedArrayBuffers in的使用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

进一步阅读:

于 2021-07-13T08:29:14.620 回答
0

正如@CherryDT 在评论中指出的那样,问题是缺少本地服务器的标头。网上搜了一下,有一篇博客介绍了在 Firefox 中使用 python 网络服务器开发 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

于 2021-07-13T08:28:40.030 回答