javascriptcorsxmlhttprequestweb-worker

Use XHR in Webworker without CORS headers or preflight answer from server


I am working on a page that will be server by a small embedded webserver that I have no control of. On the page, some data transfer (XHR) should be done inside a web worker. The server will not send any cross-origin relevant headers nor will it answer preflight OPTIONS requests reasonably.

When I put the worker javascript code into a separate file, the XHR in the worker do what they should.

But I would like to avoid the need to put two files up to the server. When I put the javascript source of the worker inside the same page and use data:text/javascript;base64,' + btoa(scripttext) for the worker, then the browser will try preflight calls to the server which fails.

What option do I have to have the worker in the same page and still be able to use XHR inside the worker successfully? I.e. how can I get the browser to treat it same-origin? I mean, it is in the same file...

Thanks!

Edit:

The browsers involved are Firefox 115.11.0esr and chromium 125.0.6422.112


Solution

  • Worker created from a data: URL have an opaque origin (step 4, "origin").
    You'll want to generate your worker from a blob: URL instead which will inherit its origin from the owner's one:

    Example as a JSfiddle since StackSnippet's null origined frames would make for an odd example:

    const workerScript = `
      postMessage(location.origin);
    `;
    const workerURL = URL.createObjectURL(new Blob([workerScript], { type: "text/javascript" }));
    const worker = new Worker(workerURL);
    worker.onmessage = ({ data }) => console.log("from worker", data);
    console.log("from main", document.origin);
    // Would log the same values