首页 > 解决方案 > 使用 iframe 显示注入的内容

问题描述

我有一个 Web 应用程序,它必须在某些地方显示 HTML 内容,这些内容来自外部来源,例如电子邮件,或者已粘贴到其他应用程序中,最终在数据库中,即我几乎无法控制 html 包含的内容。

在尝试了不同的选项后,我可以看到确保注入的 html 不会与应用程序发生冲突的最佳方法是将其注入 iframe。

我的一个担忧是,在某些边缘情况下,可能会有多个 iframe 让我们说 50 到 100。

这么多 iframe 是否会导致现代浏览器出现问题?

就内容的数量而言,这不是问题,因为它都会以一种或另一种方式出现在页面中,只是担心 iframe 是否太重的元素可能会占用太多资源而无法拥有如此大的资源数字。

编辑 我们已经在使用 ajax 加载内容,我们反复尝试“清理”内容,但似乎总是有一些我们不允许的东西,例如格式错误的 html、输入控件,甚至是我们自己的应用程序屏幕的一部分基本上任何人可以嵌入到电子邮件中的任何东西。

iframe 将允许我们将内容隔离在其自己的文档中,而不必担心它会导致应用程序的其余部分出现问题。

需要多个 iframe 是因为我们在一个地方显示电子邮件列表,并且无法控制显示的此类项目的数量,尽管通常数量很少,但在一些边缘情况下数量可能很高. 我想我们可以虚拟化屏幕以减少任何时候存在的 iframe 数量。

另一种选择是继续尝试清理内容。

标签: javascripthtmliframe

解决方案


有几件事情需要考虑:

  • iframe创建和渲染比任何其他 DOM 元素(至少是通常的元素)都要慢得多。试试这个代码:

console.time('iframe');

for (let i = 0; i < 100; i++) {
  document.body.appendChild(document.createElement('iframe'));
}
console.timeEnd('iframe'); //iframe: ~ 700ms

console.time('div');

for (let i = 0; i < 100; i++) {
  document.body.appendChild(document.createElement('div'));
}
console.timeEnd('div'); //div: ~ 1ms

  • 当然,iframe 有自己的内容,当我们加载一个包含 100 个 iframe 的页面时,就像加载内容中这 101 个页面的总和(共享内容除外,由浏览器缓存)。

  • 无论哪种方式,最重要的问题是跨站点脚本。默认情况下,如果您不使用 sanbox 属性委派任何内容,则 iframe 遵循Same Origin Policy,但如果您从同一服务器加载内容,则该策略会放宽。例如,iframe 可以重新加载顶部框架。因此,您必须非常注意在这些 iframe 中执行的内容。当然有一些方法可以缓解这个问题,一种是使用Content-Security-Policy标头。

作为结论,我会使用 ajax 而不是 iframe,因为它更快、更安全。但是,如果您发现不可能,请注意这些要点。


推荐阅读