如何使用Javascript获取iframe中的内容?

188
<iframe id="id_description_iframe" class="rte-zone" height="200" frameborder="0" title="description">
  <html>
    <head></head>
    <body class="frameBody">
      test<br/>
    </body>
  </html>
</iframe>

我想要得到的是:

test<br/>

76
重要提示:如果一个iFrame是跨域的,你将无法访问它的内容。请参考同源策略 - HellaMad
我觉得很奇怪的是,浏览器不认为我把两个文件放在本地驱动器的同一个目录下是同源的(因此不允许它们一起工作)。事实上,如果它们相互访问、通信或获取数据或内容,我不理解为什么两个文件都在c:/mypath/中且分别被称为main.html和insideiframe.html会成为浏览器的问题。如果它们一个在adomain.com中,另一个在另一个域名下,我可以理解这个问题,但是在我的本地驱动器甚至在同一个本地目录下...这似乎更像是一种过度设计。 - willy wonka
12个回答

188

确切的问题是如何使用纯JavaScript而不是jQuery来实现。

但我总是使用可以在jQuery源代码中找到的解决方案。 这只是一行本地JavaScript代码。

对我来说,这是最好的、易于阅读的,甚至是获取iframe内容最短的方法。

首先获取你的iframe

var iframe = document.getElementById('id_description_iframe');

// or
var iframe = document.querySelector('#id_description_iframe');

然后使用jQuery的解决方案。
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;

即使是Internet Explorer,它也可以通过iframe对象的contentWindow属性来实现此操作。大多数其他浏览器使用contentDocument属性,这就是为什么我们首先在此OR条件中证明此属性的原因。如果未设置,请尝试使用contentWindow.document

选择iframe中的元素

然后,您通常可以使用getElementById()甚至querySelectorAll()iframeDocument选择DOM元素:

if (!iframeDocument) {
    throw "iframe couldn't be found in DOM.";
}

var iframeContent = iframeDocument.getElementById('frameBody');

// or
var iframeContent = iframeDocument.querySelectorAll('#frameBody');

在iframe中调用函数

仅获取iframe中的window元素,以调用一些全局函数、变量或整个库(例如jQuery):

var iframeWindow = iframe.contentWindow;

// you can even call jQuery or other frameworks
// if it is loaded inside the iframe
iframeContent = iframeWindow.jQuery('#frameBody');

// or
iframeContent = iframeWindow.$('#frameBody');

// or even use any other global variable
iframeWindow.myVar = window.myVar;

// or call a global function
var myVar = iframeWindow.myFunction(param1 /*, ... */);

注意

如果您遵守同源策略,所有这些都是可能的。


2
这里未定义iframe,您应该编写完整的代码或不要与jQuery一起使用。 - Tarun Gupta
17
抱歉,但这行代码是从 jQuery 代码中摘录出来的,代码块是我自己的示例代码。其余部分应该让读者自己处理。你所缺少的只是变量 iframe。而我不可能知道你的 iframe 在哪里或它的 ID 是什么。 - algorhythm
6
请在答案顶部添加一个警告,说明如果 iframe 有一个远程 src,则此方法无效。如果我错了,请指出我如何在不发送另一个 HTTP 请求的情况下仍然可以获取 iframe 内容(这是不可能的,因为我需要执行 JavaScript 来构建 iframe 内容,而且不想部署第二个 JavaScript 环境,如果可以避免的话)。 - Zackline
1
我有一个警告。但在我的解释结束时,你必须遵守同源策略。就这样。 - algorhythm
5
为了使上述内容起作用,我不得不将其放入以下代码块中:document.querySelector('#id_description_iframe').onload = function() {...希望对某些人有所帮助。 - user3442612

74

使用jQuery,可以尝试以下代码:

$("#id_description_iframe").contents().find("body").html()

30
因为“域名、协议和端口必须匹配”,所以它不能工作:“不安全的JavaScript尝试访问具有URL”的框架。 - Ionică Bizău
3
如前所述,如果域名匹配,则可以运作。供参考,我刚刚发现在Chrome浏览器中可以使用$("#id_description_iframe #id_of_iframe_body").html()方法,但不是所有Firefox版本都可以使用,因此使用上述方法是可以的。也就是说,$("#id_description_iframe #id_of_iframe_body").contents().find("body").html()在两者中都可以使用。 - hobailey

59

对我来说它完美地工作:

document.getElementById('iframe_id').contentWindow.document.body.innerHTML;

4
有点奇怪,但对我来说.body无效。然而,.getElementsByTagName('body')[0]有效。 - Krisztián Balla
1
它不是“.body”,只是“body”。去掉那个点。 - Arjun
2
如果你熟悉原生JavaScript,那么这应该是你的答案。 - Jovanni G

26

据我所知,Iframe不能以那种方式使用。您需要将其src属性指向另一个页面。

以下是使用普通 JavaScript 获取其主体内容的方法。这适用于 IE 和 Firefox。

function getFrameContents(){
   var iFrame =  document.getElementById('id_description_iframe');
   var iFrameBody;
   if ( iFrame.contentDocument ) 
   { // FF
     iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
   }
   else if ( iFrame.contentWindow ) 
   { // IE
     iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
   }
    alert(iFrameBody.innerHTML);
 }

2
它在Safari(即分支)上运行。 - Andrei Cristian Prodan
存在跨域问题,阻止了源自"https://someOther.com"的框架访问跨源框架。 - lannyf

10

如何在使用JS的iframe中使用content

document.getElementById('id_iframe').contentWindow.document.write('content');

5

我认为在<noframes>标签中放置文本是为了适应无法处理iframe的浏览器,例如...

<iframe src ="html_intro.asp" width="100%" height="300">
  <p>Your browser does not support iframes.</p>
</iframe>

您可以使用“src”属性来设置iframe的HTML源...希望这有所帮助 :)

4

Chalkey是正确的,您需要使用src属性来指定要包含在iframe中的页面。只要您这样做,并且iframe中的文档与父文档在同一个域中,您就可以使用以下内容:

var e = document.getElementById("id_description_iframe");
if(e != null) {
   alert(e.contentWindow.document.body.innerHTML);
}

显然,您可以对内容进行一些有用的操作,而不仅仅是将其放入警告框中。

2
如果您想不仅选择iframe的主体,还要使用纯JS插入一些内容,并且没有JQuery和document.write(),我有一个解决方案,其他答案都没有提供。
您可以按照以下步骤操作:
1. 选择您的iframe:
var iframe = document.getElementById("adblock_iframe");

2.创建一个您想要插入到框架中的元素,比如一张图片:

var img = document.createElement('img');
img.src = "https://server-name.com/upload/adblock" + id + ".jpg";
img.style.paddingLeft = "450px";
//scale down the image is we have a high resolution screen on the client side
if (retina_test_media == true && high_res_test == true) {
    img.style.width = "200px";
    img.style.height = "50px";
} else {
    img.style.width = "400px";
    img.style.height = "100px";
}
img.id = "image";

3.将图像元素插入到iframe中:

iframe.contentWindow.document.body.appendChild(img);

2
以下代码兼容各种浏览器,可以在IE7、IE8、Fx 3、Safari和Chrome中正常运行,因此无需处理跨浏览器问题。未在IE6中进行测试。
<iframe id="iframeId" name="iframeId">...</iframe>

<script type="text/javascript">
    var iframeDoc;
    if (window.frames && window.frames.iframeId &&
        (iframeDoc = window.frames.iframeId.document)) {
        var iframeBody = iframeDoc.body;
        var ifromContent = iframeBody.innerHTML;
    }
</script>

以下的HTML在我的Mac上的Chrome 7中运行良好。我在Windows上的Chrome 6中测试了这篇原始文章,它也能正常工作。<html> <head> </head> <body> <iframe id="iframeId" name="iframeId">...</iframe> <script type="text/javascript">     var iframeDoc;
    if (window.frames && window.frames.iframeId && window.frames.iframeId.document) {         window.frames.iframeId.document.body.innerHTML = "<h1>测试</h1>";     } </script> </body> </html>
- nekno
2
在我的电脑上(Ubuntu 13.04,Chrome),window.frames.iframeId.document 未定义。 - Ionică Bizău

2
为了从JavaScript获取正文内容,我尝试了以下代码:

我已经尝试了以下代码:

var frameObj = document.getElementById('id_description_iframe');

var frameContent = frameObj.contentWindow.document.body.innerHTML;

其中"id_description_iframe"是您的iframe的id。 这段代码对我来说运行得很好。


3
请始终将您的回答放在上下文中,而不仅仅是粘贴代码。有关更多详细信息,请参见此处 - gehbiszumeis
1
仅提供代码的答案被认为是低质量的:请确保提供解释您的代码是如何解决问题的。如果您在帖子中添加更多信息,将有助于提问者和未来的读者。另请参阅解释完全基于代码的答案:https://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers - borchvm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接