iframe与父网站之间如何通信?


Answers:


303

在不同的域中,无法调用方法或直接访问iframe的内容文档。

您必须使用跨文档消息传递

例如在顶部窗口中:

 myIframe.contentWindow.postMessage('hello', '*');

在iframe中:

window.onmessage = function(e){
    if (e.data == 'hello') {
        alert('It works!');
    }
};

如果您要将消息从iframe发布到父窗口

window.top.postMessage('hello', '*')

2
谢谢,但是很遗憾,它在较旧的浏览器中不起作用。
丹尼·福克斯

106
在父级中:window.onmesage = function()...。在iframe中:window.top.postMessage('hello', '*')
2012年

3
这不是错误。文件url可能非常不安全,浏览器越来越谨慎地对待它们。以前,您可以file://C:/Windows/system32/whatever在网页上放置一个链接,并将其指向用户的系统文件夹中。如今,浏览器通常会忽略对此类链接的点击。运行一个网络服务器,并通过它访问您的代码,您将看到错误消失。
Stijn de Witt 2014年

4
作为一种好习惯,请不要对目标使用“ *”。实际上,MDN表示:“如果您知道另一个窗口的文档应位于的位置,则始终提供特定的targetOrigin,而不是*。未能提供特定的目标会泄露您发送给任何感兴趣的恶意站点的数据。”
rodiwa

2
我们甚至可以window.frames[index]用来获取子框架(<iframe>, <object>, <frame>),相当于getElementsByTagName("iframe")[index].contentWindow。要从IFrames中获取父窗口对象,最好使用window.parent,它window.top表示父窗口最多
Subroto

44

必须在这里,因为2012年以来的答案都可以接受

在2018和现代浏览器中,您可以将自定义事件从iframe发送到父窗口。

iframe:

var data = { foo: 'bar' }
var event = new CustomEvent('myCustomEvent', { detail: data })
window.parent.document.dispatchEvent(event)

父母:

window.document.addEventListener('myCustomEvent', handleEvent, false)
function handleEvent(e) {
  console.log(e.detail) // outputs: {foo: 'bar'}
}

PS:当然,您可以向相反方向发送事件。

document.querySelector('#iframe_id').contentDocument.dispatchEvent(event)

1
您好,我必须在同一个域中吗?
纪尧姆·哈拉里(Juillaume Harari),


1
应当注意,dispatchEvent所有主要浏览器均支持该功能。IE9是它的第一个版本,因此现在大多数操作系统都可以使用它。caniuse.com/#search=dispatchEvent
丹·阿特金森

1
我无法使用此方法从父级与iframe通信。
阿凡(Avan)

是的,我也无法使其正常工作,因为iframe js会在父窗口之后加载,因此发送时无法接收msg。对于我来说,它仅适用于从iframe到父级。
radtek

14

该库支持HTML5 postMessage和具有resize + hash的旧版浏览器https://github.com/ternarylabs/porthole

编辑:现在在2014年,IE6 / 7的使用率非常低,IE8尤其是首先得到了支持,postMessage所以我现在建议只使用它。

https://developer.mozilla.org/zh-CN/docs/Web/API/Window.postMessage


需要注意的是,IE8 / 9仅支持字符串caniuse.com/#search=postmessage(查看已知问题)
哈里

可以通过将事件对象编码为json并在另一端对其进行解码来解决此问题。
codewandler



1

使用event.source.window.postMessage发回给发件人。

来自iframe

window.top.postMessage('I am Iframe', '*')
window.onmessage = (event) => {
    if (event.data === 'GOT_YOU_IFRAME') {
        console.log('Parent received successfully.')
    }
}

然后从父母说回来。

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.