Skip to content Skip to sidebar Skip to footer

Why Are Cross Origin Workers Blocked And Why Is The Workaround Ok?

Recently I worked on a library that supports using workers for some heavy lifting. I found out that, at least on most online code editors (snippets/jsfiddle/codepen/glitch) I can't

Solution 1:

Question #1: Why do I get that error?

Because that's what the specs ask. From fetch a classic worker

  1. Let request be a new request whose url is url, client is fetch client settings object, destination is destination, mode is "same-origin", credentials mode is "same-origin", parser metadata is "not parser-inserted", and whose use-URL-credentials flag is set.

So the request will have its mode set to "same-origin", and because of that, it will fail:

(async ()=>{
const url = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js";
try {
  console.log( 'default ("no-cors")' )
await fetch( url )
  console.log( 'success' );
}
catch(e) { console.log( 'failed' ); }

try {
  console.log( 'like workers ("same-origin")' )
await fetch( url, { mode: "same-origin" } )
  console.log( 'success' );
}
catch(e) { console.log( 'failed' ); }

})();

Question #2: Is there a way to detect this issue in firefox?

Sure, you just have to listen for the error event that will be dispatched on your Worker object:

const url = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
const worker = new Worker( url );
worker.onerror = console.error;

Question #3: What's the point of this security error given the workaround is trival?

Because the internal origin of your Worker depends on this. ref

Set worker global scope's url to response's url.

So if they were to allow a "no-cors" request here, you would be able to fetch resources on that server from your Worker, bypassing the cross-origin restrictions.

By fetching it first, and then creating a same-origin (blob:URI) or an opaque origin (data:URI) context, there is no such problem.


Note that only the initial request to the Worker's script is subject to this limitation, so an other way to work around your initial issue is to use the importScripts method from inside a "same-origin" Worker:

const worker = new Worker( getURL() );
worker.onmessage = (evt) => console.log(evt.data);


function getURL() {
  const txt = document.getElementById( 'source' ).textContent;
  return URL.createObjectURL( new Blob( [ txt ] ) );
}
<script id="source" type="worker">
  importScripts("https://greggman.github.io/doodles/test/ping-worker.js");
</script>

Post a Comment for "Why Are Cross Origin Workers Blocked And Why Is The Workaround Ok?"