Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute web worker from different origin

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:

  1. Is it possible to have a worker on a remote origin for IE 10+?
  2. If 1 is the case, how is it handled best to be working cross-browser?
like image 765
MrP Avatar asked Feb 20 '14 16:02

MrP


People also ask

Can Webworkers access DOM?

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.

How many web workers web workers can run concurrently?

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.

Where should you place JavaScript code to run in the context of a web worker?

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.

What is the difference between service worker and web worker?

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.


1 Answers

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" } ) ); }
like image 167
Kaiido Avatar answered Oct 16 '22 14:10

Kaiido