2010-05-02 70 views
14

我有一个相当有趣的问题。我有一个父页面,将创建一个模式jQuery对话框与对话框中包含的iframe。 iframe将填充来自第三方域的内容。我的问题是我需要创建一些对话级别的javascript,它可以检测iframe的内容是否成功加载,并且它是否在5秒内没有,然后关闭对话框并将用户返回到父页面。跨域iframe内容负载检测

我研究了许多解决方案,只有两个是真正的价值。

  1. 获取远程站点以包含document.domain ='our-domain.com'的javascript行。
  2. 使用网址片段破解,但我需要远程站点 能够通过将#some_value附加到URL的末尾来修改URL,并且我的对话窗口必须轮询URL直到它要么看到它,要么超时。

这些老老实实是我唯一的选择吗?有没有简单的方法来检测这个?

我一直在研究是否有方法来查询http响应错误,但这仍然局限于相同的限制。

任何帮助将非常感激。

感谢

回答

10

最简单的方法(如果您可以获取代码添加到外部网站)是让他们添加一个不可见的iframe指向您的域上的特殊html文件。然后这可以使用parent.parent.foo()来通知原始窗口关于加载事件。

监听“加载”事件只会告诉你是否加载了窗口,而不是加载的内容或文档是否准备好进行交互。

+0

这听起来像是一个明确的选择。我会向开发者提出这个建议,看看他们是否会考虑这个选项。 谢谢! – 2010-07-07 11:36:22

+2

+1,用于暗示我认为是针对特定问题的* only *解决方案!谢谢。 – Town 2010-10-15 08:27:54

+0

这个工作出色,尽管有点出人意料,直到你想到它。 – Kaganar 2015-04-28 21:13:31

2

你可以尝试使用postMessage的帧之间的通信。
这将要求远程站点包含一些特定的JavaScript,以在完成加载时向父文档发布消息。

+0

我可以,是的,但只能在IE8。对不起,我应该提到,根据我们客户的规范,此功能必须适用于IE 6,7和8。 – 2010-05-02 17:37:03

+0

[无耻广告]我做了一个微型框架,以方便这一点,同时帮助您不要在您的网站上打开安全错误:https://github.com/Okrajs/Okrajs – 2015-07-24 23:23:32

3

Nicholas Zakas有一篇关于检测iframe是否加载的文章:http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/。基本上,你有这样的代码片段:

var iframe = document.createElement("iframe"); 
iframe.src = "simpleinner.htm"; 

if (iframe.attachEvent){ 
    iframe.attachEvent("onload", function(){ 
     alert("Local iframe is now loaded."); 
    }); 
} else { 
    iframe.onload = function(){ 
     alert("Local iframe is now loaded."); 
    }; 
} 

document.body.appendChild(iframe); 

我没有测试过,但我敢肯定的jQuery应该能够通过执行类似$("#iframe").load(function() { alert("Local iframe is now loaded."); });

+0

谢谢你的代码片段。我会尝试一下,看看它是如何工作的。 – 2010-05-02 19:29:53

0

在任何情况下,你会需要一些处理它如果您尝试滥用Same Origin Policy (SOP)

如果域不同,则第一个解决方案document.domain=...将不起作用。它仅适用于子域和端口,如上面的链接所述。

允许跨域通信而不进行轮询的唯一选择是JSONP或带有JS函数回调的脚本注入。此方法适用于所有Google API,并且运行良好。

我们已经在our blog上解释了一种在iframe中对这些调用进行沙箱的方法,以保护它们。虽然postMessage现在更好,但window.name hack具有在旧浏览器上工作的优势。具有讽刺意味的是,SOP不会阻止你将任何东西发布到另一个域。但是你将无法阅读回应。

+1

好吧,我并不是想“滥用”SOP政策,但是对此的需求正处于用户活动的关键阶段。 是的,我确实需要这个工作在上述浏览器上。奇怪的是,目前没有其他浏览器在他们的规范。然而! 我会去看看这些链接,并感谢您的额外信息。 – 2010-05-02 19:33:00

1

可以在iframe本身的onload处理程序上做到这一点。不幸的是(惊喜!)IE让它变得困难。唯一可以实现这个功能的方法是为iframe编写HTML,然后将其附加到innerHTML的文档中。然后我必须进行轮询以查看iframe何时出现在DOM中,这取决于页面是否加载。这是一个链接到源:http://svn.openlaszlo.org/openlaszlo/trunk/lps/includes/source/iframemanager.js

请参阅create(),__finishCreate()gotload()。随意采取这个副本,并使用它自己!

问候, 最大卡尔森 OpenLaszlo.org

+1

感谢您提供可能的解决方案,Max。我的同事&我决定尝试使用postMessage方法。虽然这不适用于IE 6和7,但我们确实发现,如果我们能够让客户同意使用postMessage,那么我们就能满足我们的迫切需求。 我会很乐意检查你的建议,尽管人们永远不会有足够的技巧。 :) – 2010-07-31 03:43:13