从主文档中的 JavaScript 获取 IFrame 的文档

IT技术 javascript html iframe document
2021-01-16 14:26:40

我有这个 HTML 代码:

<html>
  <head>
    <script type="text/javascript">
      function GetDoc(x)
      {
        return x.document ||
          x.contentDocument ||
          x.contentWindow.document;
      }

      function DoStuff()
      {
        var fr = document.all["myframe"];
        while(fr.ariaBusy) { }
        var doc = GetDoc(fr);
        if (doc == document)
          alert("Bad");
        else 
          alert("Good");
      }
    </script>
  </head>
  <body>
    <iframe id="myframe" src="http://example.com" width="100%" height="100%" onload="DoStuff()"></iframe>
  </body>
</html>

问题是我收到消息“坏”。这意味着iframe的文档没有正确获取,GetDoc函数实际返回的是父文档。

如果你告诉我哪里出错了,我将不胜感激。(我想在 IFrame 中托管文档。)

谢谢你。

4个回答

您应该能够使用以下代码访问 IFRAME 中的文档:

document.getElementById('myframe').contentWindow.document

但是,如果框架中的页面是从不同的域(例如 google.com)加载的,您将无法执行此操作。这是因为浏览器的同源策略

嗯?这将返回undefined(大多数浏览器)或<iframe>元素所在的文档(IE),这正是 OP 想要解决的问题。
2021-04-02 14:26:40
注意 iframe.contentDocument == iframe.contentWindow.document
2021-04-10 14:26:40
糟糕,我想这就是我没有先测试它的结果:-/。我刚刚编辑它以添加 contentWindow 引用。
2021-04-11 14:26:40

问题在于,在 IE 中(我假设您正在测试的内容),该<iframe>元素具有一个document属性,属性引用包含 iframe 的文档,并且在contentDocumentorcontentWindow.document属性之前使用了该属性。你需要的是:

function GetDoc(x) {
    return x.contentDocument || x.contentWindow.document;
}

此外,document.all并非在所有浏览器中都可用并且是非标准的。使用document.getElementById()来代替。

如果您遇到跨域错误:

如果您可以控制 iframe 的内容——也就是说,如果它只是在跨域设置中加载,例如在 Amazon Mechanical Turk 上——您可以使用<body onload='my_func(my_arg)'>内部 html属性来规避这个问题

例如,对于内部 html,使用thishtml 参数(是的 -this已定义,它指的是内部 body 元素的父窗口):

<body onload='changeForm(this)'>

在内部 html 中:

    function changeForm(window) {
        console.log('inner window loaded: do whatever you want with the inner html');
        window.document.getElementById('mturk_form').style.display = 'none';
    </script>

您还可以使用:

document.querySelector('iframe').contentDocument