I am developing a library which I want to host on a CDN. The library is going to be used on many different domains across multiple servers. The library itself contains one script (let's call it script.js for now) which loads a web worker (worker.js).
Loading the library itself is quite easy: just add the <script type="text/javascript" src="http://cdn.mydomain.com/script.js"></script>
tag to the domain on which I want to use the library (www.myotherdomain.com). However since the library is loading a worker from http://cdn.mydomain.com/worker.js new Worker('http://cdn.mydomain.com/worker.js')
, I get a SecurityException. CORS is enabled on cdn.mydomain.com.
For web workers it is not allowed to use a web worker on a remote domain. Using CORS will not help: browsers seem to ignore it and don't even execute the preflight check.
A way around this would be to perform an XMLHttpRequest to get the source of the worker and then create a BLOB url and create a worker using this url. This works for Firefox and Chrome. However, this does not seem to work for Internet Explorer or Opera.
A solution would be to place the worker on www.myotherdomain.com or place a proxy file (which simply loads the worker from the cdn using XHR or importScripts). I do not however like this solution: it requires me to place additional files on the server and since the library is used on multiple servers, updating would be difficult.
My question consists of two parsts:
Web workers can't access DOM elements from the web page. Web workers can't access global variables and JavaScript functions from the web page. Web workers can't call alert() or confirm() functions. Objects such as window, document and parent can't be accessed inside the web worker.
A web worker is a JavaScript program running on a different thread, in parallel with main thread. The browser creates one thread per tab. The main thread can spawn an unlimited number of web workers, until the user's system resources are fully consumed.
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.
Unlike web workers, service workers allow you to intercept network requests (via the fetch event) and to listen for Push API events in the background (via the push event). A page can spawn multiple web workers, but a single service worker controls all the active tabs under the scope it was registered with.
The best is probably to generate a simple worker-script dynamically, which will internally call importScripts()
, which is not limited by this cross-origin restriction.
To understand why you can't use a cross-domain script as a Worker init-script, see this answer. Basically, the Worker context will have its own origin set to the one of that script.
// The script there simply posts back an "Hello" message // Obviously cross-origin here const cross_origin_script_url = "https://greggman.github.io/doodles/test/ping-worker.js"; const worker_url = getWorkerURL( cross_origin_script_url ); const worker = new Worker( worker_url ); worker.onmessage = (evt) => console.log( evt.data ); URL.revokeObjectURL( worker_url ); // Returns a blob:// URL which points // to a javascript file which will call // importScripts with the given URL function getWorkerURL( url ) { const content = `importScripts( "${ url }" );`; return URL.createObjectURL( new Blob( [ content ], { type: "text/javascript" } ) ); }
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