66

Web 浏览器是否在 iframe 中为 JavaScript 使用单独的执行线程?

我相信 Chrome 为每个选项卡使用单独的线程,所以我猜测 iframe 中的 JavaScript 将与其父窗口共享相同的线程,但是,这似乎也存在安全风险。

4

10 回答 10

33

最近测试了在 iFrame 中运行的 JavaScript 是否会阻止 JavaScript 在父窗口中运行。

与父级在同一域上的 iFrame:

  • Chrome 68.0.3440.84:块
  • Safari 11.0.2 (13604.4.7.1.3):块
  • iOS 上的 Safari 15.1:块
  • Firefox 96:块

不同域上的 iFrame 作为父级

  • Chrome 68.0.3440.84:不阻止
  • Safari 11.0.2 (13604.4.7.1.3):块(过时,但我没有 macbook)
  • iOS 上的 Safari 15.1:不阻止
  • Firefox 96:不阻止
  • 适用于 Android 的 Chrome 96:有时阻止,有时不阻止(Android 版 Chrome 中有一些复杂的规则可确定 Android 版 Chrome 何时执行和不隔离进程,请参阅chrome://process-internalschrome://flags

父.html:

    <body>
    <div id="count"></div>
    <iframe src="./spin.html"></iframe>     
    <script>
        let i = 0;
        let div = document.getElementById("count");
        setInterval(() => {
            div.innerText = i++;
        }, 100);
    </script>
    </body>

自旋.html:

    <body>
    <button id="spin">spin</button>
    <script>
        const spin = document.getElementById("spin");
        spin.addEventListener('click', () => {
            const start = Date.now();
            while (Date.now() - start < 1000) { }
        })
    </script>
    </body>
于 2018-08-05T11:03:45.853 回答
23

在 chrome 出现之前,任何浏览器的所有选项卡都共享同一个 JavaScript 单线程。Chrome 在这里升级了游戏,其他一些人也纷纷效仿。

这是一个浏览器实现细节,所以没有可靠的答案。较旧的浏览器肯定不会。我不知道任何浏览器肯定会为 iframe 使用另一个线程,但老实说,我从未真正研究过它。

这不是安全风险,因为线程执行不会带来任何对象。

于 2012-07-16T18:47:28.063 回答
22

总结其他答案:不,iFrame 通常与主页在同一线程/进程中运行

但是,Chromium 团队似乎正在努力在该领域进一步隔离:

Chromium 问题 99379:进程外 iframe [抱歉,链接不起作用 - 如果您能找到有效问题的链接,请告诉我]

进程外 iframe 的设计计划

于 2014-03-13T02:18:39.767 回答
12

在检查任何现有答案之前,我今晚自己也有同样的问题。在我目前正在工作的项目中,我们必须加载一个使用不同框架的 iFrame,如果 iFrame 会以某种方式阻塞线程并影响我的应用程序,我很好奇。答案是肯定的,可以。

我的测试是在 Chrome 中完成的。在父级中,我加载了一个子 iFrame。在父级中,我设置了一个间隔来 console.log 每次发送一个文本。然后在 iFrame 中,我使用超时来启动阻塞线程的“while”。答案:iFrame 使用相同的线程。

例子:

在父级中:

setInterval(() => {
  console.log('iFrame still using the thread');
}, 3000)

在 iFrame 中:

setTimeout(() => {
  console.log('now the thread is not working in the iFrame anymore');
  while (true) {
  }
}, 10000)
于 2016-08-03T23:32:50.070 回答
6

只有桌面(不,不是移动)上的 chrome 和 firefox正在分离线程。

我创建了一个小页面,在主页中以间隔运行长循环,并在主页和 iframe 中显示动画。您可以从要检查的浏览器访问该站点。

如果较低的动画(在“crossorigin”下)不停地运行,它有一个单独的线程。

https://eylonsu.github.io/browser_thread/

于 2020-06-23T08:46:41.740 回答
5

今天在 Ubuntu 的 Chrome 28 中做了一些实验。使用此命令查看 Chrome 的线程和进程

ps axo pid,nlwp,cmd | grep "chrome"

看起来 Chrome 不会为 iframe 生成新线程或进程。有趣的是,它确实为开发工具窗格生成了一个新进程。

于 2013-06-20T18:31:00.967 回答
5

晚了,但是......好点,因为 iframe js 似乎在 Firefox 16 中是并发的。
尝试使用警报功能(阻塞),你会看到对话框一起打开。
你不会在 Chrome 或 IE 中看到它。
iframe js 可以像往常一样访问 Firefox 16 中的父窗口,所以我可以想到可能出现的竞争条件。

于 2012-11-19T15:57:06.013 回答
5

2021 年更新:

现在有Origin-Agent-Cluster允许您为 iframe 请求专用资源的标头。它目前在 Chrome (88+) 上得到支持,并得到 Mozilla 和 Safari 的好评。

Origin-Agent-Cluster 是一个新的 HTTP 响应头,指示浏览器阻止同站点跨域页面之间的同步脚本访问。浏览器也可以使用 Origin-Agent-Cluster 来暗示您的源应该获得自己的独立资源,例如专用进程。

[...] 例如,如果https://customerservicewidget.example.com希望使用大量资源进行视频聊天,并且将嵌入到各个来源https://*.example.com,则维护该小部件的团队可以使用 Origin-Agent-Cluster 标头来尝试降低其对性能的影响嵌入器。

要使用 Origin-Agent-Cluster 标头,请将您的 Web 服务器配置为发送以下 HTTP 响应标头:Origin-Agent-Cluster: ?1的值?1是布尔真值的结构化标头语法。

更多细节在这里:https ://web.dev/origin-agent-cluster/

于 2021-02-03T18:54:47.770 回答
0

2022 更新(实验性)

iframe 现在至少可以在桌面计算机上的 Chrome Canary 中并行运行,但这仍然是实验性的。

  1. 下载 Chrome Canary ( https://www.google.com/chrome/canary/ )。
  2. 导航到“chrome://flags/”。
  3. 启用“隔离沙盒 iframe”。
  4. 使用以下内容创建“index.html”:
<h1>index.html</h1>
<iframe src="index-child.html" sandbox="allow-scripts"></iframe>
<script>
    setInterval(() => {
        console.log("index.html executed one iteration");
    }, 1000)
</script>
  1. 使用以下内容创建“index-child.html”:
<h1>index-child.html</h1>
<script>
    setTimeout(() => {
        console.log("index-child.html started continuous execution");
        while (true) {
        }
    }, 3000)
</script>
  1. 在浏览器中打开“index.html”。
  2. 验证控制台是否始终如一地记录“index.html 执行一次迭代”。因此,iframe 是并行执行的。
  3. 禁用“隔离沙盒 iframe”(或仅使用其他浏览器)并再次打开“index.html”。控制台不再持续记录“index.html 执行了一次迭代”。因此,iframe 不再并行执行。

注意:必须正确设置标签sandbox上的属性才能使其正常工作。iframe此外,目前每个站点只支持一个额外的进程,这意味着多个 iframe 不会全部并行运行。

来自“chrome://flags/”的具体说明:

隔离沙盒 iframe
启用后,将进程隔离应用于具有“沙盒”属性且未在该属性上设置“允许相同来源”权限的 iframe。当前的隔离模型是将来自给定站点的所有沙盒 iframe 放入同一进程中,但在未来的实验中可能会引入替代模型。– Mac、Windows、Linux、Chrome 操作系统、紫红色

于 2022-02-25T23:39:04.387 回答
-1

对于 iFrame,没有。但是,如果您想在 JavaScript 中使用线程,您可以使用 Web Workers,这是新浏览器支持的工作 html5 草案。http://www.w3.org/TR/2009/WD-workers-20091029/

于 2013-03-06T07:53:10.990 回答