如何在iframe和父网站之间进行通信?

Dan*_*Fox 167 html javascript ajax iframe

iframe中的网站不在同一个域中,但两者都是我的,我想iframe在父网站之间进行通信.可能吗?

use*_*621 279

对于不同的域,无法直接调用方法或访问iframe的内容文档.

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

例如在顶部窗口中:

 myIframe.contentWindow.postMessage('hello', '*');
Run Code Online (Sandbox Code Playgroud)

在iframe中:

window.onmessage = function(e){
    if (e.data == 'hello') {
        alert('It works!');
    }
};
Run Code Online (Sandbox Code Playgroud)

如果要将iframe中的消息发布到父窗口

window.top.postMessage('hello', '*')
Run Code Online (Sandbox Code Playgroud)

  • 在父语句中:`window.onmesage = function()...`.在iframe中:`window.top.postMessage('hello','*')` (103认同)
  • 是的,它[在IE <= 7中不起作用](http://caniuse.com/x-doc-messaging) (3认同)
  • 这也适用于从iframe到父母的工作吗? (3认同)
  • 这不是一个错误.文件网址可能非常不安全,浏览器会越来越小心地对待它们.回到过去,您可以在网页上放置一个指向`file:// C:/ Windows/system32/whatever`的链接,并将其指向用户的系统文件夹.目前,浏览器大多忽略了对此类链接的点击.运行一个Web服务器并通过它访问您的代码,您将看到错误. (3认同)
  • 作为一个好习惯,永远不要使用'*'作为你的目标.实际上,MDN说 - "如果您知道其他窗口的文档应该位于何处,则始终提供特定目标原始文件,而不是*.未提供特定目标会泄露您发送给任何感兴趣的恶意网站的数据." (3认同)
  • 谢谢,但遗憾的是它不适用于旧版浏览器. (2认同)
  • 我们甚至可以使用`window.frames[index]`来获取子框架(`&lt;iframe&gt;, &lt;object&gt;, &lt;frame&gt;`),相当于`getElementsByTagName("iframe")[index].contentWindow`。要从 IFrame 获取父窗口对象,最好使用 `window.parent`,因为 `window.top` 代表最顶层的父窗口 (2认同)

Str*_*e Q 28

它必须在这里,因为2012年接受了答案

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

IFRAME:

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

父:

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

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

document.querySelector('#iframe_id').contentDocument.dispatchEvent(event)
Run Code Online (Sandbox Code Playgroud)

  • 我无法使用此方法从父级到 iframe 进行通信。 (4认同)
  • /sf/ask/1756861501/ (3认同)
  • 你好,我必须在同一个域上才能这样做吗? (2认同)
  • 我测试了它,它仅适用于同源框架。跨域访问“window.parent”时会导致“SecurityError” (2认同)

jpi*_*ora 14

这个库支持HTML5 postMessage和旧版浏览器resize + hash https://github.com/ternarylabs/porthole

编辑:现在在2014年,IE6/7的使用率相当低,IE8及以上版本都支持,postMessage所以我现在建议只使用它.

https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage


Bin*_* Ho 5

使用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.')
    }
}
Run Code Online (Sandbox Code Playgroud)

然后从父母说回来。

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
Run Code Online (Sandbox Code Playgroud)

  • 截至 2021 年 3 月撰写本文时,对“window.onmessage”的跨浏览器支持尚未完成:https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onmessage#browser_compatibility (2认同)