React错误:Firefox中未定义“SharedArrayBuffer”

21

我有一个使用'create-react-app'创建的React应用程序(我还使用了jsdom NPM包),由于某种原因,该应用程序在加载时仅在Firefox中抛出错误(在Chrome和Edge中正常工作)。
以下是错误信息:

ReferenceError: SharedArrayBuffer is not defined
./node_modules/jsdom/node_modules/webidl-conversions/lib/index.js
C:/Or/Web/WorldCovid/WorldCovid/node_modules/jsdom/node_modules/webidl-conversions/lib/index.js:347

  344 | 
  345 | const abByteLengthGetter =
  346 |     Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength").get;
> 347 | const sabByteLengthGetter =
  348 |     Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, "byteLength").get;
  349 | 
  350 | function isNonSharedArrayBuffer(V) {
在一些搜索之后,我发现:
“要在Firefox中启用SharedArrayBuffer,请转到about:config,并将javascript.options.shared_memory首选项设置为true” (https://github.com/ggerganov/kbd-audio/issues/9)
问题是它已经被启用为真了。
有人之前遇到过这个问题吗? 谢谢。 更新: 尝试转换为:
const shared = new SharedArrayBuffer(1024);

const abByteLengthGetter =
    Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength").get;
const sabByteLengthGetter =
    Object.getOwnPropertyDescriptor(shared.prototype, "byteLength").get;

仍然会出现相同的错误(与SharedArrayBuffer对象不同的行)。


1
你正在测试哪个版本的 Firefox?自版本 79 开始,这不需要任何 pref flipping即可支持。请参见该页面上的兼容性表格。 - Dexter
1
我正在使用Firefox 82.0.2 (64-bit)并收到此异常。 - Or Assayag
1
你是否查看了MDN页面的“安全要求”部分?出于安全原因,您可能需要一些跨源魔法。请参阅Mozilla Hacks博客文章,了解为什么需要这样做以缓解Spectre安全漏洞。 - Dexter
1
我也遇到了同样的问题 - 就像 @OrAssayag 描述的那样,而且只在 Firefox 中出现。我也使用了create-react-appjsdom npm包(以及 axios)。 - Ed Graham
3
jsdom 对我触发了错误。 - jake
4个回答

19

1
当你没有编译静态构建或使用服务器端渲染时,如何在React中进行此操作? - Jim
请告诉我如何在ReactJS项目中实现它。 - Lê Vũ Huy
MDN文档中提到COEP也可以是“无凭证”的;这在Chrome上可以工作,但在Firefox上直到我将其设置为“require-corp”才能隔离。 - undefined

9
React问题已经被修复并在17.0.2版本中发布。他们表示没有计划将更改回溯到旧版本,但这不应该是一个大问题,除非你期望在React上进行高精度性能测量。
Spectre发现以来,除Chrome桌面版外,所有浏览器都已禁用SharedArrayBuffer,但从Chrome 92开始,Chrome桌面版也会禁用它。您需要"跨源隔离"才能启用它。
当您在Chrome上遇到问题:Uncaught ReferenceError: SharedArrayBuffer is not defined时,您需要应用"跨源隔离"来继续使用SharedArrayBuffer,但作为一种逃生措施,您可以请求起点试用程序,以允许列入白名单的站点继续使用SharedArrayBuffer,至少直到Chrome 96。
要启用跨源隔离,您必须像@stephane k.在另一个评论中提到的那样发送两个HTTP标头(COOP和COEP)。
要了解有关跨源隔离的更多信息,请阅读:
- Android Chrome 88和Desktop Chrome 92中的SharedArrayBuffer更新 - 使用COOP和COEP使您的网站“跨源隔离” - 为什么您需要“跨源隔离”以获得强大的功能

4

如前所述,由于Spectre漏洞,除非您指定Cross-Origin-Opener-PolicyCross-Origin-Embedder-Policy标头,在大多数浏览器上禁用了SharedArrayBuffer。

如果您想在本地的React开发服务器上激活这些标头,您可以使用自定义中间件手动配置代理来添加标头。

创建一个src/setupProxy.js文件,其中包含:

module.exports = function (app) {
    app.use(function (req, res, next) {
        res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
        res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
        next();
    });
};

3
在index.html文件中,您可以添加以下类似的脚本。我认为这将会很有帮助。我也这样做了。
<body>
<script>
  if (!crossOriginIsolated) SharedArrayBuffer = ArrayBuffer;
</script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="app"></div>

6
这将防止SharedArrayBuffer在工作线程和主线程之间共享,这很可能会破坏依赖于SharedArrayBuffer的代码。如果你能容忍工作线程实际上不起作用,并且只是试图消除一个对应用程序没有真正影响的错误,那么这个解决方案是一个好的快速修复方法,但如果你不知道自己在做什么,你可能只是掩盖了一个可能会在未来引起问题的问题。如果你控制工作线程的代码,最好的做法可能就是根本不要运行工作线程。 - Brandon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接