iframe跨域通信

该文章发布于 ,归类于 Javascript

html5新增了一个方法postMessage,可以实现不同iframe之间进行消息传递。

语法:

otherWindow.postMessage(message, targetOrigin, [transfer]);

otherWindow:将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。

targetOrigin:通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。

transfer(可选):是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

语法内容参考自MDN

在接收消息的窗体中,可以添加message事件监听,它的回调函数第一个参数是一个Event对象,包含了三个不同的属性

data: 消息
origin: 消息来源地址
source: 源DOMWindow对象

该方法的兼容性如下图所示,可以看到IE最低支持到11,而且还是部分支持,所以在使用的时候,兼容性的问题不容忽视。

举个例子看一下iframe之间是如何通信的。

首先是父窗体,首先获得子iframe的window引用,然后使用postMessage向子窗体传递消息。

<p>I am parent!</p>
<iframe src="child.html" frameborder="0" id="sub-iframe"></iframe>
<script>
    window.onload = function () {
        var subWindow = document.getElementById('sub-iframe').contentWindow;
        subWindow.postMessage({ message: 'The message from parent' }, '*');
    }
</script>

然后是子窗体,在子窗体中监听message事件,当有新消息传递过来时,将会触发回调函数。

<style>
    .red {color: red;}
</style>
<p>I am child</p>
<script>
    addEventListener('message', function (e) {
        if (e.data.message) {
            var div = document.createElement('div');
            var text = document.createTextNode(e.data.message);
            div.appendChild(text);
            div.classList.add('red');
            document.body.appendChild(div);
        }
    }, false);
</script>

最终,会在页面打印出The message from parent,如下图所示。

相关文章