完成IFRAME加载后的JavaScript回调?
IFRAME完成加载后,我需要执行一个回调。我无法控制IFRAME中的内容,因此无法从那里触发回调。
这个IFRAME是通过编程方式创建的,我需要将其数据作为变量传递给回调,以及销毁iframe。
有任何想法吗?
编辑:
这是我现在所拥有的:
function xssRequest(url, callback) { var iFrameObj = document.createElement('IFRAME'); iFrameObj.src = url; document.body.appendChild(iFrameObj); $(iFrameObj).load(function() { document.body.removeChild(iFrameObj); callback(iFrameObj.innerHTML); }); }
该回调在iFrame加载之前进行,因此回调没有返回任何数据。
解决方案
过去,我遇到了完全相同的问题,找到解决此问题的唯一方法是将回调添加到iframe页面中。当然,只有在我们可以控制iframe内容时,该方法才有效。
在我的项目中,我有一个类似的代码可以正常工作。
使我的代码适应功能,可能有以下解决方案:
function xssRequest(url, callback) { var iFrameObj = document.createElement('IFRAME'); iFrameObj.id = 'myUniqueID'; document.body.appendChild(iFrameObj); iFrameObj.src = url; $(iFrameObj).load(function() { callback(window['myUniqueID'].document.body.innerHTML); document.body.removeChild(iFrameObj); }); }
也许我们有一个空的innerHTML,因为(一个或者两个原因):
1.我们应该对身体元素使用它
2.我们已从页面DOM中删除了iframe
首先,使用函数名称xssRequest听起来好像我们正在尝试跨站点请求,如果正确的话,我们将无法读取iframe的内容。
另一方面,如果iframe的URL在域中,则可以访问正文,但是我发现,如果我使用超时来删除iframe,则回调可以正常工作:
// possibly excessive use of jQuery - but I've got a live working example in production $('#myUniqueID').load(function () { if (typeof callback == 'function') { callback($('body', this.contentWindow.document).html()); } setTimeout(function () {$('#frameId').remove();}, 50); });
在将word docs和pdf等文档流式传输到iframe并找到一个效果很好的解决方案的情况下,我不得不这样做。关键是在iframe上处理" onreadystatechanged"事件。
可以说框架名称是" myIframe"。首先在代码启动的某个位置(我在iframe之后的任何位置进行内联)添加类似以下内容以注册事件处理程序:
document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;
我无法在iframe上使用onreadystatechage属性,我不记得为什么,但是该应用程序必须在IE 7和Safari 3中运行,因此这可能是一个因素。
这是如何获取完整状态的示例:
function MyIframeReadyStateChanged() { if(document.getElementById('myIframe').readyState == 'complete') { // Do your complete stuff here. } }
我认为加载事件是正确的。
不正确的是我们用来从iframe内容dom中检索内容的方法。
我们需要的是在iframe中加载的页面的html,而不是iframe对象的html。
我们要做的是使用iFrameObj.contentDocument
访问内容文档。
如果它位于当前页面的同一域中,则将返回加载到iframe中的页面的dom。
在删除iframe之前,我会先整理一下内容。
我已经在Firefox和Opera中测试过。
然后我认为我们可以使用$(childDom).html()或者$(childDom).find('some selector')...检索数据。
iframe的innerHTML是空白的,因为iframe标记不会围绕父文档中的任何内容。为了从iframe的src属性所引用的页面获取内容,我们需要访问iframe的contentDocument属性。但是,如果src来自其他域,则会引发异常。这是一项安全功能,可防止我们在其他人的页面上执行任意JavaScript,这会产生跨站点脚本漏洞。这是一些示例代码,说明了我在说什么:
<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script> <h1>Parent</h1> <script type="text/javascript"> function on_load(iframe) { try { // Displays the first 50 chars in the innerHTML of the // body of the page that the iframe is showing. // EDIT 2012-04-17: for wider support, fallback to contentWindow.document var doc = iframe.contentDocument || iframe.contentWindow.document; alert(doc.body.innerHTML.substring(0, 50)); } catch (e) { // This can happen if the src of the iframe is // on another domain alert('exception: ' + e); } } </script> <iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>
为了进一步说明该示例,请尝试将其用作iframe的内容:
<h1>Child</h1> <a href="http://www.google.com/">Google</a> <p>Use the preceeding link to change the src of the iframe to see what happens when the src domain is different from that of the parent page</p>