iframe 和父站点之间如何通信?

IT技术 javascript html ajax iframe
2021-02-08 01:27:14

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

6个回答

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

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

父级 -> iframe

例如在顶部窗口中:

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

并在 iframe 中:

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

iframe -> 父级

例如在顶部窗口中:

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

并在 iframe 中:

window.top.postMessage('hello', '*')
我们甚至可以使用window.frames[index]来获取子帧 ( <iframe>, <object>, <frame>),相当于getElementsByTagName("iframe")[index].contentWindow要从 IFrame 中获取父窗口对象,最好使用window.parent,作为window.top表示最顶层的父窗口
2021-03-13 01:27:14
这不是一个错误。文件 url 可能非常不安全,浏览器会越来越小心地对待它们。在过去,您可以file://C:/Windows/system32/whatever在网页上放置一个链接,并将其指向用户的系统文件夹。如今,浏览器大多忽略对此类链接的点击。运行网络服务器并通过它访问您的代码,您将看到错误显示。
2021-03-27 01:27:14
在父级中:window.onmesage = function().... 在 iframe 中:window.top.postMessage('hello', '*')
2021-03-31 01:27:14
谢谢,但不幸的是它在旧浏览器中不起作用。
2021-04-02 01:27:14
作为一个好习惯,永远不要对目标使用“*”。事实上,MDN 说 - “如果您知道另一个窗口的文档应该位于何处,则始终提供特定的 targetOrigin,而不是 *。如果不提供特定的目标,则会泄露您发送给任何感兴趣的恶意站点的数据。”
2021-04-08 01:27:14

在 2018 年和现代浏览器中,您可以将自定义事件从 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)
Avan 和@radtek 有一个简单的解决方案。您所要做的就是首先从 iframe 向父级分派一个事件,通知父级 iframe 已加载(本质上是“就绪消息”)。父级将侦听消息,如果它收到“就绪消息”事件,则它可以使用您要发送的任何消息回复 iframe。这样它只会在 iframe 加载后才将消息发送到 iframe。当然,iframe 页面只会在加载后将消息发送给父级。
2021-03-13 01:27:14
你好,我必须在同一个域上才能这样做吗?
2021-03-23 01:27:14
我无法使用此方法从父级到 iframe 进行通信。
2021-04-01 01:27:14
应该注意的dispatchEvent是,所有主要浏览器都支持。IE9 是它的第一个版本,所以现在大多数操作系统都可以使用它。caniuse.com/#search=dispatchEvent
2021-04-05 01:27:14

这个库支持 HTML5 postMessage 和带有调整大小+哈希的旧浏览器https://github.com/ternaryabs/porthole

编辑:现在在 2014 年,IE6/7 的使用率很低,IE8 和以上都支持,postMessage所以我现在建议只使用它。

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

需要注意的是 IE8/9 仅支持字符串caniuse.com/#search=postmessage(请参阅已知问题)
2021-03-22 01:27:14
这可以通过将您的事件对象编码为 json 并在另一端解码来解决。
2021-04-04 01:27:14

使用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', '*')
}
在撰写本文时,即 2021 年 3 月,跨浏览器支持window.onmessage尚未完成:developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/...
2021-03-15 01:27:14
@flyingace 我所知道的唯一警告是 IE 上的跨域 iframe 消息传递。你知道现代浏览器之间的任何差距吗?
2021-04-01 01:27:14

window.top物业应该能够满足您的需求。

例如

alert(top.location.href)

http://cross-browser.com/talk/inter-frame_comm.html

由于 iframe 不在同一个域中,因此他无法访问其父域。
2021-03-23 01:27:14