I ran into an interesting problem while creating a hosted API that relies on web workers. I was hoping to get a little community feedback on it.
My server is set up with the appropriate CORS headers to deliver the worker JS files and can be retrieved with an XMLHttpRequest
object. However, when the URL is given to new Worker()
it fails to build, citing the origin being the problem. This seems to be an issue on both Firefox and Chrome. Check it out for yourself, and my workaround, here: http://jsfiddle.net/5ag42hb1/11/
Is this not odd behaviour? Mozilla docs say that Web Workers must obey same-origin policy and to use CORS to allow cross-origin access.
The fiddle has a workaround of storing the file in a blob and passing that to the worker instead. It seems less than ideal though, introducing a lot of unnecessary complexity. Can anyone think of a cleaner solution? Is there a good channel to get this implemented properly?
Since web workers are in external files, they do not have access to the following JavaScript objects: The window object. The document object. The parent object.
to fix the error, you need to enable CORS on the server. The client expects to see CORS headers sent back in order to allow the request. It might even send a preflight request to make sure that the headers are there. You can enable CORS server side for one, multiple, or all domains hitting your server.
You can run whatever code you like inside the worker thread, with some exceptions. For example, you can't directly manipulate the DOM from inside a worker, or use some default methods and properties of the window object.
I did a lot of digging and asked around on IRC channels. I got some pretty good answers thanks to the guys in #developers on the Mozilla network. Hopefully this will help anyone in the same situation as me.
To sum it up, the HTML spec outlines that running new Worker('http://remoteorigin.com/worker.js')
should execute the worker with the remote origin's security context. Something that's like CORS but not quite because it's execution rights instead of reading rights.
So why isn't that how it works right now? Because browsers haven't implemented the full spec yet. Chalk it up as something to look forward to.
Until then, there are actually 2 workarounds. I outlined the blob method above but we also can use importScripts(). If you can't modify the Worker itself, you could probably make a shell Worker that simply implements the Worker you actually want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With