【问题标题】:Why does jQuery remove body and head tags when populating an iframe with a style tag but not without?为什么在使用样式标签而不是没有样式标签填充 iframe 时,jQuery 会删除 body 和 head 标签?
【发布时间】:2012-04-21 01:44:42
【问题描述】:

如果我运行以下代码,则会删除 body 和 head 标签。

<iframe src='blank.htm'>
    <html>
    <head>
        <style type="text/css">

        </style>
    </head>
    <body>
        test
    </body>
    </html>
</iframe>
<script>
    $('iframe').load(function () {
        var contents = $('iframe').text();
        $('iframe').contents().find('html').html(contents);
    });
</script>

如果我然后删除样式标签,一切都会正确显示。为什么会这样,我怎样才能让它停止删除头部和身体标签?我希望内容按原样填充,无需任何操作。

【问题讨论】:

  • 你为什么要这样做?你能详细说明吗?想到的快速下意识的反应是“不要那样做”,但我怀疑你为什么这样做是有原因的,你没有告诉我们? :) 如果您告诉我们您的目标是什么,我认为我们可以提供更好的帮助。祝你好运!
  • 我正在创建一个沙箱,允许我为最终用户正确显示 html 模板。考虑预览一封电子邮件,您需要在另一个 Web 窗口中查看最终结果。如果没有沙箱,您将强加不属于消息内容的其他样式和格式,反之亦然。此代码允许我在 iframe 出现在页面上后对其进行填充,而不会影响我的其余代码或页面本身。
  • 这是一个预览窗格,因此内容不一定在当时任何其他地方,因此为什么我不只是用信息加载另一个页面。
  • 好的,有道理!这有助于将问题置于我们的上下文中。 +1。考虑将信息合并到上面的问题框中:) 有趣的问题!

标签: javascript jquery iframe


【解决方案1】:

我遇到了同样的问题并从this SO question 了解到,实际上是浏览器进行了剥离,作为其解析innerHTML 属性的一部分,这是jQuery.html() 内部使用的。

相反,问题实际上是jQuery使用了一个中间新的DIV,我认为它不允许包含某些标签,导致剥离。

那么解决办法。就像直接设置html元素的innerHTML属性一样简单,像这样:

// This forcibly removes head, body, and other tags, since it internally uses an empty DIV and its innerHTML property
jQuery(targetElement).html(exitHtml);

// This works fine
h = document.getElementsByTagName('html')[0];
h.innerHTML = htmlString;

对于您的特定情况,只需将html 元素定位到内部 iframe。 您的最终代码可能是:

<script>
    $('iframe').load(function () {
        var contents = $('iframe').text();
        iframeHtml = $('iframe').contents().find('html').get(0);
        iframeHtml.innerHTML = contents;
    });
</script>

【讨论】:

  • 同意。这回答了问题,而接受的答案是技术上有趣的旅程,但不是答案。
【解决方案2】:

您可以按照以下步骤了解如何将 iframe 内容复制到字符串、修改它并在 iframe 中替换它。这些步骤旨在在您的 Chrome 调试器中执行,仅用于教育/演示目的。一旦你了解了这个过程,你就可以尝试在你的网站上复制你的代码。

在 Chrome 调试器中一次运行一个函数:

// test iframe I loaded in a sandbox also at http://example.com
$('body div:first').before('<iframe src="http://example.com/company"></iframe>');

// retrieved the body of the iframe - I cloned it so I could perform operations
  // on the copy without bothering the iframe content.
iBody = $('iframe:first').contents().find('body').clone();

// got the head
iHead = $('iframe:first').contents().find('head').html();

// if there is script in the body, it really messes things up. So in my tests, 
  // I had to remove it before adding it back to the iframe.
iBody.find("script").remove();

// verify there are no script elements
ibody.html(); 

// replace the iframe head
$('iframe:first').contents().find('head').html(iHead);

// replace the iframe body first with a placeholder. The body is the sensitive 
  // part. If you destroy the DOM, it can make the entire page, including 
    // the parent, turn completely white.
$('iframe:first').contents().find('body').html('<div></div>');

// ** inserted something in the copy to prove we modified it!!
iBody.append("<div style='position:absolute;z-index:5000; color:red; " + 
    "background-color:white;'>JAMES WAS HERE</div>");

// now replace the body
$('iframe:first').contents().find('body').html(iBody);

在网站底部的 iframe 内,我看到我的消息在白色背景上显示为红色。我也可以在源代码中看到它:

$('iframe:first').contents().find('body').html();

我在一个匿名网站上执行了这些操作,使用 Chrome 的调试器控制台运行命令。第一个命令在主页中创建一个 iframe,该 iframe 中包含网站的公司页面。其余命令获取该 iframe 的头部和主体,克隆主体,添加一些内容,例如“JAMES WAS HERE”消息到主体克隆,然后用该副本替换 iframe 主体。

我还通过在浏览器中加载 http://getsatisfaction.com 并在 iframe 中加载 http://getsatisfaction.com/explore/product-innovation 来验证相同的结果。通过重复上述步骤,我看到了我的消息“JAMES WAS HERE”。

**我遇到的最严重的问题是无法将 JavaScript 或 CSS 样式标签留在副本中。样式的解决方案是在将正文添加回 iframe 之前进行所有样式修改。 **

由于某种原因,浏览器试图运行 JavaScript 并抛出错误。这些错误的上下文让我认为 JavaScript 是在顶级上下文而不是 iframe 上下文中运行的!这对你来说可能是个大事。您可能需要制定另一个计划,以便在弹出窗口或内联中显示预览。此外,这可能在具有不同 JavaScript 的不同网站上表现不同。它在 IE 中的行为也可能很奇怪。

简而言之,我实际上并不认为该解决方案可以支持生产网站,因为必须在 iframe 中删除 JavaScript;但是,根据您的需要,如果您不需要 iframe DOM 来使用任何 JavaScript,则可以在生产环境中使用它。

不过,这是一个值得探索的有趣问题!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 2013-09-16
    相关资源
    最近更新 更多