HTML 5 PostMessage / Detect iFrame无法加载
我们有一些代码利用HTML 5中的新postMessagefunction来解决跨域通信问题。 我正试图找到一种方法来检测我是否正在将消息发布到正确加载其内容的iFrame。 如果帧无法正确加载,postMessage不会知道这一点,并且很乐意将消息发布到无响应的帧中(我假设消息正在传递到帧,无论是否加载了它的内容)。
这是我们的工作流程:
- 用户加载http://www.a.com/specialpage.aspx
- a.com/specialpage.aspx反过来加载一个子iFrame,其源代码设置为来自另一个域的代理页面,例如http://www.b.com/lookatmyproxy.htm 。
- 用户执行某些操作,单击按钮
- window.postMessage用于将消息发布到子帧,其中(希望)由加载帧的代理(b.com/lookatmyproxy.htm)拾取。 收到邮件后,将validation,处理邮件,并将回复发回给父框架(a.com/specialpage.aspx)。
- 用户会看到他们行动的结果,大家都很开心。
问题的情况是,如果b.com关闭并且代理无法加载到iFrame中,postMessage将只会触发并忘记,并且父框架永远不会收到错误或任何类型的回复。 iframe的安全问题和性质似乎阻止我检查框架内容或状态,以确定代理是否正确加载。 我可以把一个带有一些超时逻辑的继电器放在a.com和b.com之间控制(a.com发布到a.com/relay,然后发布到b.com/proxy等) ,但这似乎过于复杂。
有没有办法让我检查iFrame并告诉它的内容是否正确加载,或者检测到postMessage正在传递给源无法加载的帧?
这不是最干净的答案,但我能够解决我的问题。 我发现的是一些旧文档,虽然安全性不允许您从其他帧读取信息,但您可以调用某些函数。 在较旧的浏览器中,这用于欺骗帧以设置彼此的url片段并导致操作发生。 这里有一个很好的参考:
http://softwareas.com/cross-domain-communication-with-iframes
由于允许使用postMessage,我的代理所做的第一件事就是将“已加载”的消息发布到其父帧(如果存在)。 代理看起来像这样:
//tell the parent that we're functional var data = '{ "action" : "Loaded" }'; if (parent && parent.frames && parent.frames[0] && parent.frames[0].content) { parent.frames[0].content.postMessage(data, '*'); } window.addEventListener("message", function (e) { if (e.domain == undefined) { //do something } }, false);
另一方面,我的页面会侦听该消息,并在收到该消息时设置变量以显示正确加载的代理。 如果他们从未收到消息,则所有操作都假定代理不可用,并且UI会相应地做出反应以阻止用户操作。 看起来像这样:
$(document).ready(function () { window.addEventListener("message", function (e) { var args = (e.data && (e.data.length > 0)) ? JSON.parse(e.data) : {}; if (args.action) { if (args.action == 'Loaded') { if (typeof ProxyLoaded_success == 'function') { ProxyLoaded_success(args); } } } }, false); }); var proxyLoaded = false; function ProxyLoaded_success(args) { proxyLoaded = true; } function abc() { if(proxyLoaded == true) { //do something here } else { alert("proxy didn't load. call support"); } }