Cross Domain Web Worker?

Viewed 10967

I have https://domain1.com (domain1) and https://domain2.com (domain2).

Domain2 serves a page containing javascript with this header:

"Access-Control-Allow-Origin: *"

Domain1 runs some javascript code that invokes:

new Worker("//domain2.com/script.js")

Browsers throw security exceptions.

Since starting writing this question, I have got around this problem by ajaxing the script, blobbing it and running it from that, but am I missing something in the original idea?

4 Answers

Note : The URI passed as parameter of the Worker constructor must obey the same-origin policy. There is currently disagreement among browsers vendors on what URIs are of the same-origin; ...

Quote from https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers

The HTML5 Worker is a fairly new concept and I'm not sure how same-origin exceptions apply, however, with XmlHttpRequest, it's possible to access resources on a different domain if you have control over the the server it runs on. Resources on foreign domains are accessed via preflighted requests meaning that first an OPTIONS request is sent to resource and if the response to that has the appropriate access control headers (Access-Control-Allow-Methods, Access-Control-Allow-Origin as a minimum), then the request is repeated with the original method and receives the resource in response.

Note: does not seem to work since Chrome v93+, but John Hou's solution works like a charm! (though it's much easier nowadays to use fetch to retrieve the code instead of XMLHttpRequest)


It's pretty funny, but importScripts() inside the worker does not have the same origin restriction. So I used this plain workaround:

const workerUrl = 'https://domain2.com/script.js';
const workerBlob = new Blob([
    'importScripts(' + JSON.stringify(workerUrl) + ')',
], {type: 'application/javascript'});
const blobUrl = window.URL.createObjectURL(workerBlob);
const worker = new Worker(blobUrl);

Somewhat simpler than fetching script manually.

Do you have allow methods set?

Try adding this to your header:

Access-Control-Allow-Methods: POST, GET, OPTIONS
Related