title: Why are cross origin workers blocked and why is the workaround ok?
body: <p>Recently I worked on <a href="https://github.com/greggman/unzipit" rel="nofollow noreferrer">a library</a> that supports using workers for some heavy lifting.</p>
  
  <p>I found out that, at least on most online code editors (snippets/jsfiddle/codepen/glitch) I can't seem to load a worker from another domain. I get a security error (or in firefox silent failure)</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>function startWorker(url) {
    try {
      const worker = new Worker(url);
      console.log('started worker');
      worker.onmessage = e =&gt; log('black', e.data);
      worker.postMessage('Hi from page');
    } catch (e) {
      console.error('could not start worker:', e);
    }
  }
  
  const workerURL = 'https://greggman.github.io/doodles/test/ping-worker.js';
  startWorker(workerURL);</code></pre>
  </div>
  </div>
  </p>
  
  <p>In Chrome and Safari I get</p>
  
  <blockquote>
    <p>SecurityError: Failed to construct 'Worker': Script at '<a href="https://greggman.github.io/doodles/test/ping-worker.js" rel="nofollow noreferrer">https://greggman.github.io/doodles/test/ping-worker.js</a>' cannot be accessed from origin 'https://...'.</p>
  </blockquote>
  
  <h2>Question #1: Why do I get that error?</h2>
  
  <p>What setting causes it? iframe options? http headers for the page? http headers for the iframe? http headers from the script?)</p>
  
  <h2>Question #2: Is there a way to detect this issue in firefox?</h2>
  
  <p>I can send a message from the worker and timeout but I'm wondering if there is some less indirect way of checking for success/failure</p>
  
  <p>In any case I can work around this issue by fetching the text of the script myself</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>function startWorker(url) {
    try {
      const worker = new Worker(url);
      console.log('started worker');
      worker.onmessage = e =&gt; console.log(e.data);
      worker.postMessage('Hi from page');
    } catch (e) {
      console.error('could not start worker:', e);
    }
  }
  
  async function main() {
    const workerURL = 'https://greggman.github.io/doodles/test/ping-worker.js';
  
    const res = await fetch(workerURL);
    const text = await res.text();
    const blob = new Blob([text], {type: 'application/javascript'});
    const url = URL.createObjectURL(blob);
  
    startWorker(url);
  }
  main();</code></pre>
  </div>
  </div>
  </p>
  
  <p>I asked the browser teams and was told fetching manually and making a blob url is okay which leads to my <strong>main question</strong>. </p>
  
  <h2>Question #3: What's the point of this security error given the workaround is trival?</h2>
  
  <p>Given there is a workaround in what situation is there no workaround? What is the point of the Security Error? The browser vendors say my workaround is fine and I've actually be using the ability launch things as blob urls for 7-8 years. (html, scripts, but not workers until now) but if my workaround is fine then what is the point of the error?</p>