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


74

我有这个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中。)

谢谢。


3
有人在2010年提出要求,今天是2015年,除非您使用google.com,否则在任何较新的浏览器中都无法使用。由于跨源策略,如果iframe指向的页面与加载原始文档的页面不在同一域,则无法访问该iframe的内容。
aorcsik 2015年

Answers:


156

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

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

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


3
??这将返回undefined(大多数浏览器)或<iframe>元素所在的文档(IE),而这恰恰是OP想要解决的问题。
Tim Down

糟糕,我想这就是我不首先测试它的结果:-/。我刚刚对其进行了编辑,以添加contentWindow引用。
2010年

13
请注意iframe.contentDocument == iframe.contentWindow.document
destan 2013年

15

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

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

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


2

如果您遇到跨域错误:

如果您可以控制iframe的内容-也就是说,如果仅将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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.