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

我想使用jQuery在iFrame中操作超文本标记语言。

我想我可以通过将jQuery函数的上下文设置为ifram的文档来做到这一点,类似于:

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

然而,这似乎不起作用。一些检查表明,除非我等待一段时间以加载ifram,否则frames['nameOfMyIframe']中的变量是undefined。然而,当ifram加载时,变量是不可访问的(我得到permission denied类型的错误)。

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

735288 次浏览

你有没有试过经典的,等待加载完成使用jQuery的内置就绪函数?

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

K

您需要将事件附加到ifram的onload处理程序,并在其中执行js,以便在访问它之前确保ifram已完成加载。

$().ready(function () {$("#iframeID").ready(function () { //The function below executes once the iframe has finished loading$('some selector', frames['nameOfMyIframe'].document).doStuff();});};

上面的内容将解决“尚未加载”的问题,但就权限而言,如果您在ifram中加载来自不同域的页面,则由于安全限制,您将无法访问它。

我认为你正在做的事情受到同源政策的影响。这应该是你得到权限拒绝类型错误的原因。

如果<iframe>来自同一个域,则元素很容易访问

$("#iFrame").contents().find("#someDiv").removeClass("hidden");

参考

您可以使用jQuery的.contents()方法。

.contents()方法也可用于获取ifram的内容文档,如果ifram与主页位于同一域中。

$(document).ready(function(){$('#frameID').load(function(){$('#frameID').contents().find('body').html('Hey, i`ve changed content of <body>! Yay!!!');});});

如果iframesrc来自另一个域,您仍然可以这样做。您需要将外部页面读入PHP并从您的域中回传它。像这样:

iframe_page.php

<?php$URL = "http://external.com";
$domain = file_get_contents($URL);
echo $domain;?>

然后是这样的:

display_page.html

<html><head><title>Test</title></head><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){cleanit = setInterval ( "cleaning()", 500 );});
function cleaning(){if($('#frametest').contents().find('.selector').html() == "somthing"){clearInterval(cleanit);$('#selector').contents().find('.Link').html('ideate tech');}}
</script>
<body><iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php" ></iframe></body></html>

以上是如何通过ifram编辑外部页面而不会拒绝访问等的示例…

使用

iframe.contentWindow.document

而不是

iframe.contentDocument

我觉得这样更干净:

var $iframe = $("#iframeID").contents();$iframe.find('selector');

我更喜欢使用其他变体进行访问。从父级,您可以访问子ifram中的变量。$也是一个变量,您可以接收对其只是调用的访问window.iframe_id.$

例如,window.view.$('div').hide()-使用id“view”隐藏ifram中的所有div

但是,它在FF中不起作用。为了更好的兼容性,您应该使用

$('#iframe_id')[0].contentWindow.$

您可以使用window.post消息在page和他的ifram之间调用函数(跨域或不跨域)。

文档

page.html

<!DOCTYPE html><html><head><title>Page with an iframe</title><meta charset="UTF-8" /><script src="http://code.jquery.com/jquery-1.10.2.min.js"></script><script>var Page = {id:'page',variable:'This is the page.'};
$(window).on('message', function(e) {var event = e.originalEvent;if(window.console) {console.log(event);}alert(event.origin + '\n' + event.data);});function iframeReady(iframe) {if(iframe.contentWindow.postMessage) {iframe.contentWindow.postMessage('Hello ' + Page.id, '*');}}</script></head><body><h1>Page with an iframe</h1><iframe src="iframe.html" onload="iframeReady(this);"></iframe></body></html>

iframe.html

<!DOCTYPE html><html><head><title>iframe</title><meta charset="UTF-8" /><script src="http://code.jquery.com/jquery-1.10.2.min.js"></script><script>var Page = {id:'iframe',variable:'The iframe.'};
$(window).on('message', function(e) {var event = e.originalEvent;if(window.console) {console.log(event);}alert(event.origin + '\n' + event.data);});$(window).on('load', function() {if(window.parent.postMessage) {window.parent.postMessage('Hello ' + Page.id, '*');}});</script></head><body><h1>iframe</h1><p>It's the iframe.</p></body></html>

我创建了一个示例代码。现在你可以很容易地理解你无法访问的不同域ifram的内容…我们可以访问ifram内容的同一个域

我分享你我的代码,请运行此代码检查控制台。我在控制台打印图像src。有四个ifram,两个ifram来自同一个域,另外两个来自其他域(第三方)。你可以看到两个图像src(https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif

https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif)在控制台,也可以看到两个权限错误(2错误:访问属性“文档”的权限被拒绝

… irstChildren)},内容:函数(a){返回m.node名称(a,"ifram")?a.content文档…

)来自第三方iFrame。

<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>

为了更加稳健:

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;}

...var frame_win = getIframeWindow( frames['nameOfMyIframe'] );
if (frame_win) {$(frame_win.contentDocument || frame_win.document).find('some selector').doStuff();...}...

我最终在这里寻找没有jQuery的ifram的内容,所以对于其他寻找它的人来说,它只是这样:

document.querySelector('iframe[name=iframename]').contentDocument

此解决方案的工作原理与iFrame相同。我创建了一个PHP脚本,可以从其他网站获取所有内容,最重要的是您可以轻松地将自定义jQuery应用于该外部内容。请参阅以下脚本,它可以从其他网站获取所有内容,然后您也可以应用您的同义词jQuery/JS。此内容可以在任何地方、任何元素或任何页面中使用。

<div id='myframe'>
<?php/*Use below function to display final HTML inside this div*/
//Display Frameecho 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 menuYou can write your own jQuery for this content*///Hide Navigation barjQuery(\".navbar.navbar-default\").hide();
</script>";
//Append Custom JS with HTML$html = $content . $customJS;
//Return customized HTMLreturn $html;}

如果下面的代码不起作用

$("#iFrame").contents().find("#someDiv").removeClass("hidden");

以下是使其工作的可靠方法:

$(document).ready(function(){setTimeout(function () {$("#iFrame").contents().find("#someDiv").removeClass("hidden");},300);});

这样脚本将在300毫秒后运行,因此它将有足够的时间加载iFrame,然后代码将生效。有时iFrame没有加载,脚本会尝试在它之前执行。300ms可以根据您的需要调整为其他任何东西。