18

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?

Dull Bananas
  • 892
  • 7
  • 29
user1277170
  • 3,127
  • 3
  • 19
  • 19
  • There's a duplicate [here](http://stackoverflow.com/questions/4415382/how-do-i-make-worker-work-against-cross-domain) and [here](http://stackoverflow.com/questions/18881875/how-to-get-web-workers-to-function-cross-domain-multiple-browsers-ie-script502) but none of them seem to have a definitive answer. – adeneo Dec 05 '13 at 20:37
  • Using the ajax - data URL approach won't work in all browsers, according to [the MDN page](https://developer.mozilla.org/en-US/docs/Web/API/Worker.Worker). – Pointy Dec 05 '13 at 20:41
  • 2
    And as far as I can tell from the W3C spec, the rules imply that worker scripts really do have to be sourced from the same domain as the owning page. I don't think that CORS headers are even checked. – Pointy Dec 05 '13 at 20:46
  • @Pointy Figures, since the network tab doesn't even suggest that it's even fetching the page to check. So if AJAX can do it, why can't we do it direct? :/ – user1277170 Dec 05 '13 at 21:02
  • I don't know the rationale behind the way it works. In the case of ajax, well, that's an older standard. And again note that using that workaround won't necessarily work, as some browsers will consider that data URL that you build to *not* count as "same origin" for a web worker. – Pointy Dec 05 '13 at 21:08
  • this may get you solve this. http://stackoverflow.com/questions/21913673/execute-web-worker-from-different-origin – Jiby Jose Sep 22 '14 at 09:07

4 Answers4

13

I also have the same problem, hope this can help you https://gist.github.com/jtyjty99999/a730a17258fca04bfca3

 function XHRWorker(url, ready, scope) {
      var oReq = new XMLHttpRequest();
      oReq.addEventListener('load', function() {
          var worker = new Worker(window.URL.createObjectURL(new Blob([this.responseText])));
          if (ready) {
              ready.call(scope, worker);
          }
      }, oReq);
      oReq.open("get", url, true);
      oReq.send();
  }

  function WorkerStart() {
      XHRWorker("http://static.xxx.com/js/worker.js", function(worker) {
          worker.postMessage("hello world");
          worker.onmessage = function(e) {
              console.log(e.data);
          }
      }, this);
  }

  WorkerStart();
John Hou
  • 219
  • 2
  • 11
  • Just a note that this does not work on IE11 and below. That set of browsers throw a `SecurityError`. – Yuriy Nemtsov Jan 12 '17 at 17:04
  • Wow, like this solution. Especially chaining ```new Blob``` with ```URL.createObjectURL```. Didn't know it's possible. – Artur May 21 '18 at 16:10
8

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.

Klesun
  • 12,280
  • 5
  • 59
  • 52
5

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.

marekful
  • 14,986
  • 6
  • 37
  • 59
  • 1
    This is true. However, from the description of the web worker script fetching process, it's not clear that a user agent is even supposed to check for the headers. It simply forces the URL to be fetched from the owning page origin, and it sets the "force same-origin flag" to ensure that redirects can't affect that. – Pointy Dec 05 '13 at 21:08
  • I'm not sure... The quoted doc says "In addition, they can perform I/O using XMLHttpRequest ...". In light of this I assume the underlying transport is still standard HTTP requests. – marekful Dec 05 '13 at 21:15
  • Oh yes, I think that's true. But the [spec](http://www.w3.org/TR/workers/#processing-model) suggests to me that the user agent is supposed to fetch scripts only from the "owner origin". – Pointy Dec 05 '13 at 21:21
  • The spec on this is ambiguous about `owner origin`. Clearly, the MDN doc says that "The URI passed as parameter of the Worker constructor must obey the same-origin policy" and about Same Origin Policy, it says that cross-origin accesses are allowed under certain conditions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript?redirectlocale=en-US&redirectslug=JavaScript%2FSame_origin_policy_for_JavaScript#Cross-origin_network_access – marekful Dec 05 '13 at 21:34
  • And this makes sense because the goal of restrictions on cross-origin access is to prevent accessing a resource when its owner doesn't want it to be accessed. But if you are the owner of the multiple origins, you may cross access resources among them. – marekful Dec 05 '13 at 21:38
  • I agree with that, but [the W3C wording makes it seem stricter than that](http://www.w3.org/TR/workers/#processing-model). – Pointy Dec 05 '13 at 21:44
  • By spec I meant the W3 spec. In 4.6 the fist sentence defines url, owner document, owner browsing context, etc. but does not define relation between them nor it mentions cross-origin. – marekful Dec 05 '13 at 21:56
  • Look at 4.6 (Processing Model) number 3. It says it fetches from the "owner origin" explicitly. – Pointy Dec 05 '13 at 22:31
-3

Do you have allow methods set?

Try adding this to your header:

Access-Control-Allow-Methods: POST, GET, OPTIONS
Lenny
  • 5,663
  • 2
  • 19
  • 27