を必要とするマルチスレッドを使用する WebAssembly ベースのソフトウェアを使用していますSharedArrayBuffer
。ローカル/展開された Chromium、および展開された Firefox 89 の両方で問題なく動作しますが、最高のパフォーマンスは Firefox の下にあるため、自分のマシンでテストして調整したいので、python -m SimpleHTTPServer
. この状況で、Firefox で 127.0.0.1:8000 または 0.0.0.0:8000 を開くと、SharedArrayBuffer
undefinedです。おそらくこれはセキュリティ設定ですが、localhost を使用している場合、Firefox の状況解釈にはあまり関心がありません。これは実行する必要があります。どうすればそれを機能させることができますか?別の Web サーバーや別の設定が必要ですか?
2 に答える
ご想像のとおり、これはセキュリティ上の制限に関係しています。SharedArrayBuffer
Firefox 79 ですでに実装されているの使用に関して変更があり、間もなく Chrome にも導入されます (Chrome 92 以降)。(これを書いている時間: 2021 年 7 月 13 日。)
主な目的は、 でSharedArrayBuffer
の sの使用を制限することです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
参考文献:
コメントで @CherryDT が指摘したように、問題はローカル サーバーのヘッダーが欠落していることです。ネットを検索すると、Python Web サーバーを使用して Firefox で 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