我如何将消息传递给兄弟iFrame

时间:2012-09-16 22:29:26

标签: javascript iframe xss postmessage

我正在寻找一种方法将postMessage发送到兄弟iFrame,而父页面中没有任何javascript。我遇到的困难是尝试从第一个iFrame中获取另一个iFrame的窗口对象

页面的布局如下:

html body (http://host.com/)
  iFrame#a (http://me.com/a)
  iFrame#b (http://me.com/b)

来自iFrame#a我正在尝试:

(iFrame#b window).postMessage(...)

问题是我不知道如何从iFrame#b内获取iFrame#a的窗口对象。 parent.getElementById()和其他功能受XSS限制。我只想向父网页上的所有其他iFrame发出postMessage,这些iFrame来自我上面示例中的http://me.com/域。

2 个答案:

答案 0 :(得分:7)

虽然确实无法与另一个域上的另一个窗口/ iframe进行交互,但 可以获得对此类窗口/ iframe的引用以及嵌入的所有子iframe进入那个窗口/ iframe。这样做的方法是使用window.top.frames(访问顶部窗口对象)或window.parent.frames(访问直接父窗口对象,而可能有其他更高级别的祖先)。无需使用getElementById或其他与DOM相关的功能。有关详情,请参阅此处:https://developer.mozilla.org/en-US/docs/DOM/window.frames

window.frames属性返回一个类似于数组的对象,然后您可以迭代并在每个iframe上执行postMessage。这不会触发同源限制,因为除了在它们上使用postMessage之外,您不会以任何方式与任何窗口进行交互。由于您想在特定域的每个iframe上执行postMessage,您可以这样做:

var frames = window.parent.frames;
for (var i = 0; i < frames.length; i++) { 
  frames[i].postMessage("hello", targetDomain);
}

答案 1 :(得分:3)

您将无法执行此操作,因为iframe无法与其所覆盖的页面(也不是该页面内的任何内容)进行交互,除非父级位于同一域(在您的示例中,不是)。如果可以,它会在您表明您知道的情况下造成XSS安全问题。

相反,你可以:

  • 在/ a /中设置一个cookie并在/ b /中对它进行轮询(这会很昂贵,因为/ b /必须以某种方式继续调用服务器)
  • 使用'HTML5'持久数据存储机制,在/ b /中存储来自/ a /的数据并对其进行轮询(可能会使用localStorage
  • 使用websocket通过服务器链接所有兄弟姐妹
  • 重新考虑你想要做的事情:你想要达到的目标听起来很奇怪 - 你确定没有比使用像这样的iframe更好的办法吗?