如何使用JavaScript/jQuery访问iframe的内容?

857

我想使用jQuery操纵iframe内部的HTML。

我以为可以通过将jQuery函数的上下文设置为iframe的文档来实现,类似于:

$(function(){ //document ready
    $('some selector', frames['nameOfMyIframe'].document).doStuff()
});

然而这似乎行不通。稍微检查一下,我发现要等一段时间iframe加载后frames['nameOfMyIframe']中的变量才会变成 undefined。但是,当iframe加载时,变量却无法访问(我会收到类似于permission denied的错误)。

有没有人知道解决这个问题的方法?


3
iFrame 包含什么内容 - 它的 src 是否设置为另一个域名? - James
如果是其他领域,是否仍有办法访问其内容或注册事件? - adardesign
38
不行,因为这将涉及跨站脚本攻击,出于安全原因被禁止。 我的解决方案是使用代理:将IFRAME中的HTML程序透过我的网站原封不动地传送,这样从浏览器的角度来看就不再是跨站了。 - reinierpost
1
最好使用 .contentWindow.document 而不是在 iframe 元素上使用 .document,这样可以更好地跨浏览器兼容。我建议以上更改。 - Alan H.
1
一种方法是使用Chrome扩展程序。 - Muhammad Umer
15个回答

2

我创建了一个示例代码。现在你可以轻松理解,从不同的域名访问时,你无法访问iframe内容。相同的域我们可以访问iframe内容。

我分享了我的代码,请运行这段代码并检查控制台。我在控制台打印图片src。有四个iframe,两个来自同一域,另外两个来自其他域(第三方)。你可以看到两个图片src(https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gifhttps://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif),同时也可以看到两个权限错误(2 Error: Permission denied to access property 'document'),这是来自第三方iframe的。

...irstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument...

<body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top">
<p>iframe from same domain</p>
  <iframe frameborder="0" scrolling="no" width="500" height="500"
   src="iframe.html" name="imgbox" class="iView">

</iframe>
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
   src="iframe2.html" name="imgbox" class="iView1">

</iframe>
<p>iframe from different  domain</p>
 <iframe frameborder="0" scrolling="no" width="500" height="500"
   src="https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif" name="imgbox" class="iView2">

</iframe>

<p>iframe from different  domain</p>
 <iframe frameborder="0" scrolling="no" width="500" height="500"
   src="http://d1rmo5dfr7fx8e.cloudfront.net/" name="imgbox" class="iView3">

</iframe>

<script type='text/javascript'>


$(document).ready(function(){
    setTimeout(function(){


        var src = $('.iView').contents().find(".shrinkToFit").attr('src');
    console.log(src);
         }, 2000);


    setTimeout(function(){


        var src = $('.iView1').contents().find(".shrinkToFit").attr('src');
    console.log(src);
         }, 3000);


    setTimeout(function(){


        var src = $('.iView2').contents().find(".shrinkToFit").attr('src');
    console.log(src);
         }, 3000);

         setTimeout(function(){


        var src = $('.iView3').contents().find("img").attr('src');
    console.log(src);
         }, 3000);


    })


</script>
</body>

2
你尝试过使用jQuery内置的ready函数来等待加载完成吗?
$(document).ready(function() {
    $('some selector', frames['nameOfMyIframe'].document).doStuff()
} );

K


2
是的。当主框架加载时,ready函数开始执行--而不是iframe加载时。等待似乎只是问题的一小部分,我认为这与跨域安全有关。 - rz.

1
我在这里寻找获取iframe内容而不使用jquery的方法,所以对于其他寻找此方法的人,只需要这样做:
document.querySelector('iframe[name=iframename]').contentDocument

1
这个解决方案与iFrame相同。我创建了一个PHP脚本,可以获取其他网站的所有内容,最重要的是您可以轻松地将自定义jQuery应用于外部内容。请参考以下脚本,可以获取其他网站的所有内容,然后您也可以应用自定义的jQuery / JS。此内容可以在任何元素或页面内使用。
<div id='myframe'>

  <?php 
   /* 
    Use below function to display final HTML inside this div
   */

   //Display Frame
   echo displayFrame(); 
  ?>

</div>

<?php

/* 
  Function to display frame from another domain 
*/

function displayFrame()
{
  $webUrl = 'http://[external-web-domain.com]/';

  //Get HTML from the URL
  $content = file_get_contents($webUrl);

  //Add custom JS to returned HTML content
  $customJS = "
  <script>

      /* Here I am writing a sample jQuery to hide the navigation menu
         You can write your own jQuery for this content
      */
    //Hide Navigation bar
    jQuery(\".navbar.navbar-default\").hide();

  </script>";

  //Append Custom JS with HTML
  $html = $content . $customJS;

  //Return customized HTML
  return $html;
}

这会怎么工作?如果您将$customJS字符串附加到$content,那么您将在外部域的关闭HTML标记之后拥有脚本元素吗? - ultrageek

1

为了更加健壮:

function getIframeWindow(iframe_object) {
  var doc;

  if (iframe_object.contentWindow) {
    return iframe_object.contentWindow;
  }

  if (iframe_object.window) {
    return iframe_object.window;
  } 

  if (!doc && iframe_object.contentDocument) {
    doc = iframe_object.contentDocument;
  } 

  if (!doc && iframe_object.document) {
    doc = iframe_object.document;
  }

  if (doc && doc.defaultView) {
   return doc.defaultView;
  }

  if (doc && doc.parentWindow) {
    return doc.parentWindow;
  }

  return undefined;
}

"and"(并且)
...
var frame_win = getIframeWindow( frames['nameOfMyIframe'] );

if (frame_win) {
  $(frame_win.contentDocument || frame_win.document).find('some selector').doStuff();
  ...
}
...

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