跨域 IFrame 通信 - 一种跨浏览器解决方案






4.90/5 (24投票s)
本技巧将帮助您与添加到表单中的跨域 IFrame 进行通信。
引言
本技巧提供了一种非常简便易懂的方式来处理跨域 IFrame
通信。
背景
最近,我加入了公司 MS Dynamics CRM 团队。
我在所做项目中有一个需求 - 在 CRM 表单内放置一个 IFrame
,该 IFrame 位于不同的域中,并将一些数据从 IFrame
推送到 Parent
窗口。但由于同源策略,它不允许从不同域获取数据。因此,我进行了一些搜索并参考了一些文章。
最终,我找到了一种解决方案,它是一个跨浏览器解决方案。下面我将详细解释。
Using the Code
我们需要使用 window.postMessage 来完成这项任务。
语法如下
window.postMessage(message, targetOrigin);
在 IFrame 中
我们将编写以下代码,以向 Parent
窗口/表单发布/发送消息。
window.parent.postMessage("Hello From IFrame", "*");
注意: '*' 作为 targetOrigin 参数表示没有偏好,否则您可以指定 Parent Window/要发布消息的窗口 的域,如下所示
window.parent.postMessage("Hello From IFrame", "http://example.com");
这个 targetOrigin
参数是消息传递到的窗口的域。如果 Parent
窗口关联有任何端口号,那么您也需要将其提及 (例如:http://example.com:8080)。这需要完全正确,否则消息将无法发布。
在 Parent Window 中
我们将编写以下代码,以侦听 IFrame
发布的消息。
// Here "addEventListener" is for standards-compliant web browsers and "attachEvent" is for IE Browsers.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
// Now...
// if
// "attachEvent", then we need to select "onmessage" as the event.
// if
// "addEventListener", then we need to select "message" as the event
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child IFrame window
eventer(messageEvent, function (e) {
alert(e.data);
// Do whatever you want to do with the data got from IFrame in Parent form.
}, false);
为了安全起见
我们应该始终将 targetOrigin
参数作为目标窗口/Parent 窗口的 Url 发送。
我们还需要检查事件的origin 或 发起窗口/IFrame 的 Url。这是因为任何恶意网站都可能发送数据或操纵数据。
因此,接收器的安全代码如下所示...
// Listen to message from child IFrame window
eventer(messageEvent, function (e) {
if (e.origin == 'http://iframe.example.com') {
alert(e.data);
// Do whatever you want to do with the data got from IFrame in Parent form.
}
}, false);
这里 IFrame
的域/发布消息的 origin 是 'http://iframe.example.com'。
关注点
您也可以反过来做。这意味着您可以从 Parent
窗口向 IFrame
传递消息,并在 IFrame
中接收相同的消息。
参考文献
历史
- 2013 年 5 月 2 日 - 首次提交版本以供批准