I am using a WebAssembly based software that uses multi-threading that requires SharedArrayBuffer
. It runs fine both in Chromium local/deployed, and Firefox 89 deployed, but since the best performance is under Firefox, I want to test and tune it on my machine, so I run python -m SimpleHTTPServer
. In this situation, when I open 127.0.0.1:8000 or 0.0.0.0:8000 in Firefox, SharedArrayBuffer
is undefined. Perhaps this is a security setting, but when using localhost, I'm really not interested in Firefox's interpretation of the situation -- this should just run. How can I make it work? Do I need a different web server, different settings?

- 66,707
- 21
- 171
- 266
-
1You might be missing the necessary HTTP headers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/Planned_changes – CherryDT Jul 13 '21 at 08:15
-
@CherryDT any idea how to set them up with simplehttpserver, or with nginx? – 0__ Jul 13 '21 at 08:20
-
I thought of an easier way, because it sounds like you don't pass the object through `postMessage` anyway - see my answer – CherryDT Jul 13 '21 at 08:29
2 Answers
As you guessed correctly, it has to do with security restrictions. There have been changes in regards to the use of SharedArrayBuffer
that have already been implemented in Firefox 79 and will land in Chrome shortly as well (starting with Chrome 92). (Time of writing this: July 13, 2021.)
The main purpose is to restrict the use of SharedArrayBuffer
s in postMessage
. Any such attempt will throw an error unless certain restrictive COOP/COEP headers are set to prevent cross-origin attacks:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Unfortunately, without these headers, there is also no global SharedArrayBuffer
constructor. Apparently, this restriction may be lifted in the future. The objects themselves still work though (only passing them through postMessage
would throw), but you need a different way to instantiate them. You can use WebAssembly.Memory
instead:
const memory = new WebAssembly.Memory({ initial: 10, maximum: 100, shared: true })
// memory.buffer is instanceof SharedMemoryBuffer
You could now go one step further and recover the constructor from that. Therefore, with the following code as "shim", your existing code should work as long as it doesn't try to pass the buffer through 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
Further reading:

- 25,571
- 5
- 49
- 74
As @CherryDT pointed out in the comment, the problem is missing headers for the local server. Searching the net, there is a blog that walks through the process of developing WebAssembly in Firefox with a python web server. Instead of python -m SimpleHTTPServer
, one has to add a file ./wasm-server.py
with this contents (for 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()
then it is possible to test the application at 127.0.0.1:8080

- 66,707
- 21
- 171
- 266