7

I am working on React + WASM + FFmpeg app following this tutorial

On Chrome, I got the error Uncaught (in promise) ReferenceError: SharedArrayBuffer is not defined error.

I followed the doc reference, and it says the below, which I don't understand.


Cross-origin isolation overview

You can make a page cross-origin isolated by serving the page with these headers:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

What does serving the pages with these headers mean?

How do I implement that?

I even found Chrome dev's official video, but even that does not explain any implementation detail.

Edit2: The best instruction I can find is here, but even that is too vague for me. What does it mean by setting a header? I'm not requesting anything to begin with.

Edit: My React version is already 17.0.2, so this should have been fixed but I am somehow getting this error as well...

[Deprecation] SharedArrayBuffer will require cross-origin isolation as of M92, around July 2021.

Leonard
  • 2,978
  • 6
  • 21
  • 42

4 Answers4

4

Let's start off by saying what serving the pages with these headers means.

If you have ever built an API with Express.js for example, you'll be familiar with this. Essentially, it means that when the user makes a GET request to see the web page, you will have to send some additional information in the form of HTTP headers.

Specifically, the first header prevents your page from loading any cross-origin resources that don't explicitly grant permission. The second one means that you can't share a browsing context group with any cross-origin documents. Both of these are used as safety measures to prevent cross-origin attacks. Even though you may not be requesting anything, you have to apply them.

Now onto your problem, I would recommend installing the Chrome extension CORS. I don't know exactly how it works, but I have used it in the past and it will be a temporary solution. I skimmed through the tutorial you're following and I didn't see a server setup (as in Express.js/Node's http for instance). If you had any of these you could pass the headers as arguments to the servers.

To check if the CORS settings are working as intended, add the following code to your app:

if (crossOriginIsolated) {
    // Works
}
Diogenis Siganos
  • 779
  • 7
  • 17
  • Thanks. But yeah this does not use any server setup. Hence I'm really confused as to where to set http request headers, or even how to do that... – Leonard Aug 02 '21 at 05:52
  • I am not sure about that either. Try out the CORS thing I mentioned and let me know if it works. If you're looking for something more permanent or are not satisfied you could consider wrapping everything in a web server – Diogenis Siganos Aug 02 '21 at 06:07
  • https://scotch.io/tutorials/react-on-the-server-for-beginners-build-a-universal-react-and-node-app – Diogenis Siganos Aug 02 '21 at 06:08
4

The SharedArrayBuffer serves the purpose of sharing data buffers between your main browsing context and another agent (another web page or a worker).

However, to minimize the possible security vulnerabilities, the specification states that this API can only be operated in a secure context.

In addition to this security prerequisite, it is also necessary for any top-level document to be in a Cross Origin Isolation. This means, the party serving the contents should tell the browser that it should block the loading of cross-origin resources. (A document from domain A trying to get data from Domain B)

This is done by the servers by specifying the following two response eaders when serving the website:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

How to specify them in your debug environment?

You need to set up a standard file server such as Apache. Then you will have to tweak its configuration to serve the above headers with the files.

Quick setup: https://www.wampserver.com/en/

An answer provisioning the header info: https://stackoverflow.com/a/35566100/4185234

Charlie
  • 22,886
  • 11
  • 59
  • 90
  • This is great, and I applied the headers, but now my web worker won't load even though it's also localhosted on the same server! – Pete Sep 08 '22 at 15:44
0

I ran into this recently and found your question and the answers above

What does serving the pages with these headers mean?

It means configuring the server serving your pages to include those headers. How you configure a server depends on the software you're using, Apache, Nginx, Caddy, or if you're using one of the 1000s of others or writing your own.

I've written 2 (or more correctly, I've used a library to write 2) and I added the option to include those headers. Both are open source so you can look inside if you want to see how they work.

If you prefer a UI then there's this one. If you prefer the command line then install node.js and then you can use this one

gman
  • 100,619
  • 31
  • 269
  • 393
0

Here's a static server example for node.js

var http = require("http");
var fs = require("fs");
var path = require("path");

http
  .createServer(function (request, response) {
    console.log("request starting...");

    response.setHeader("Cross-Origin-Opener-Policy", "same-origin");
    response.setHeader("Cross-Origin-Embedder-Policy", "require-corp");

    var filePath = "." + request.url;
    if (filePath == "./") filePath = "./index.html";

    var extname = path.extname(filePath);
    var contentType = "text/html";
    switch (extname) {
      case ".js":
        contentType = "text/javascript";
        break;
      case ".css":
        contentType = "text/css";
        break;
      case ".json":
        contentType = "application/json";
        break;
      case ".png":
        contentType = "image/png";
        break;
      case ".jpg":
        contentType = "image/jpg";
        break;
      case ".wav":
        contentType = "audio/wav";
        break;
    }

    fs.readFile(filePath, function (error, content) {
      if (error) {
        if (error.code == "ENOENT") {
          fs.readFile("./404.html", function (error, content) {
            response.writeHead(200, { "Content-Type": contentType });
            response.end(content, "utf-8");
          });
        } else {
          response.writeHead(500);
          response.end(
            "Sorry, check with the site admin for error: " +
              error.code +
              " ..\n"
          );
          response.end();
        }
      } else {
        response.writeHead(200, { "Content-Type": contentType });
        response.end(content, "utf-8");
      }
    });
  })
  .listen(80);
console.log("Server running at http://127.0.0.1:80/");
patrick
  • 16,091
  • 29
  • 100
  • 164