Iframe 中的 SharedArrayBuffer

问题描述 投票:0回答:3

因此 SharedArrayBuffer 最近限制为跨源隔离页面作为安全修复。

我们有一个依赖于 SharedArrayBuffer 的工具,我对它进行了重新设计,将其移动到剥离了所有其他站点 UI 和其他内容的准系统页面,并发送以下标头: Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin

尝试将其加载到成熟网站的 iframe 中会出现控制台错误 
SharedArrayBuffer will require cross-origin isolation as of M92

,然后是

ReferenceError: SharedArrayBuffer is not defined
- 与我在跨原点隔离最小页面本身上的工具之前得到的结果相同。
我尝试包含 iframe 的页面是 

not

跨域隔离的。这样做即使不是不可能,也是非常困难的。我根本不需要从父页面与 iframe 进行交互,这只是一个方便/风格的事情。目前生产上的解决方案只是将用户链接到新窗口中的最小跨源工具页面,但这非常尴尬。 我希望的是 iframe

sandbox 属性

的某种组合或其他东西可以使这项工作起作用?我为此奋斗了几个小时。 据我所知,这可能不可行。

javascript html iframe sharedarraybuffer
3个回答
1
投票
allow-scripts

属性中添加

allow-same-origin
sandbox
标记:
<iframe src="…" sandbox="allow-scripts allow-same-origin"></iframe>
                         ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^

以下是有关该主题的一些相关资源:

首先尝试上述方法,如果它对解决您遇到的
SharedArrayBuffer

问题没有帮助,那么事情会有点复杂。

正确的跨域需要来自子资源的显式标头(

<iframe>

必须发送标头),当子资源是第三方且失控时,这是一个大问题。为了缓解这个问题,有一个

提案
Cross-Origin-Embedder-Policy: credentialles
但是,有一个问题:

它不会改变

<iframe>的工作方式

(真糟糕,这正是我们所需要的!)。有一个关于匿名 iframe 的讨论可以解决这个问题,但它还没有解决,所以我不会在这里屏住呼吸。
因此,剩下的唯一选择是延迟 Chrome 行为中的此更改

(可以在 Chrome 103 之前完成):

请求您的来源的令牌
  1. 将令牌添加到您的页面。有两种方法可以做到这一点: 在每个页面的头部添加一个
  2. <meta>
  3. 标签。例如,这可能看起来像:
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • 如果您可以配置服务器,您还可以使用 
      Origin-Trial
      HTTP 标头添加令牌。生成的响应标头应类似于:
    • Origin-Trial: TOKEN_GOES_HERE
    • 
      
      
      
我不确定此选项是否适合您的情况,但也许它可以帮助您找到完整的解决方案。 这篇
blogpost

0
投票

页面第一次加载时,会注册一个 Service Worker

页面已重新加载
  1. SharedArrayBuffer 变得可用,因为 ServiceWorker 控制所有请求的所有 CORS 标头
  2. Service Worker 通过添加 CORS/COEP 标头来修改所有请求(示例取自上述博文):

self.addEventListener("install", function() { self.skipWaiting(); }); self.addEventListener("activate", (event) => { event.waitUntil(self.clients.claim()); }); self.addEventListener("fetch", function(event) { if (event.request.cache === "only-if-cached" && event.request.mode !== "same-origin") { return; } event.respondWith( fetch(event.request) .then(function(response) { // It seems like we only need to set the headers for index.html // If you want to be on the safe side, comment this out // if (!response.url.includes("index.html")) return response; const newHeaders = new Headers(response.headers); newHeaders.set("Cross-Origin-Embedder-Policy", "require-corp"); newHeaders.set("Cross-Origin-Opener-Policy", "same-origin"); const moddedResponse = new Response(response.body, { status: response.status, statusText: response.statusText, headers: newHeaders, }); return moddedResponse; }) .catch(function(e) { console.error(e); }) ); });


    

答案迟了,但是对于任何寻求解决方案的人来说。


0
投票

Cross-Origin-Embedder-Policy: credentialless

代替:

Cross-Origin-Embedder-Policy: require-corp

© www.soinside.com 2019 - 2024. All rights reserved.