2

我正在寻找一种在父页面中没有任何 javascript 的情况下将消息发布到兄弟 iFrame 的方法。我遇到的困难是尝试从第一个 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#aparent.getElementById()和其他功能受 XSS 限制。在上面的示例中,我只想向postMessage父页面上来自我的域的所有其他 iFrame发出 a 。http://me.com/

4

2 回答 2

10

虽然不可能与另一个域上的另一个窗口/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);
}
于 2012-09-17T11:40:44.827 回答
2

您将无法执行此操作,因为 iframe 无法与其嵌入的页面(也不是该页面中的任何内容)进行交互,除非父级位于同一域下(在您的示例中,它不是)。如果可以的话,它会造成 XSS 安全问题,正如您所指出的那样。

相反,您可以:

  • 在 /a/ 中设置一个 cookie 并在 /b/ 中轮询它(这会很昂贵,因为 /b/ 必须以某种方式继续调用服务器)
  • 使用“HTML5”持久数据存储机制,从 /a/ 存储数据并在 /b/ 中轮询(也许可以使用localStorage )
  • 使用websocket通过服务器链接所有兄弟姐妹
  • 重新考虑您要做什么:您要实现的目标听起来很奇怪-您确定没有比使用这样的 iframe 更好的做事方式吗?
于 2012-09-16T22:54:01.770 回答