持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
在不同源页面中通信
跨文档消息(XDM)是一个在不同执行上下文中传递消息的能力。
核心
核心是利用 postMessage() 方法,可以把一个数据传递到另一个地方,另一个地方监听,然后拿到数据。 但是前提是双方都要同意并且调用相应的js。
以下是这个方法的两个部分
postMessage
postMessage() 方法接受三个参数
参数:
-
data要发送的数据。可以是任何对象,数据会被通过使用序列化进行克隆。IE 浏览器只支持字符串,因此我们需要对复杂的对象调用
JSON.stringify方法进行处理,我们最好是转化 string 字符串,避免有些浏览器不支持。 -
targetOrigin指定目标窗口的源,以便只有来自给定的源的窗口才能获得该消息。
<iframe src="http://example.com" name="example">
<script>
let win = window.frames.example;
win.postMessage("message", "http://example.com");
</script>
现在只有example.com下的消息才会被win接收,这样的安全策略很重要
也可以把targetOrigin设置为 * 但是不建议这样。。。
onMessagge
为了接收数据,目标窗口会有一个message的事件,等发送了消息,并且检查targetOrigin成功。
event 事件对象具有特殊属性:
-
data从
postMessage传递来的数据。 -
origin发送方的源,例如
http://example.com。 -
source对发送方窗口的引用。如果我们想,我们可以立即
source.postMessage(...)回去。
要为 message 事件分配处理程序,我们应该使用 addEventListener,简短的语法 window.onmessage 不起作用。
使用如下
window.addEventListener("message", function(event) {
if (event.origin != 'http://example.com') {
// 来自未知的源的内容,我们忽略它
return;
}
alert( "received: " + event.data );
// 可以使用 event.source.postMessage(...) 向回发送消息
});
总结
要调用另一个窗口的方法或者访问另一个窗口的内容,我们应该首先拥有对其的引用。
就是要过去到窗口,比如
window.frames—— 一个嵌套的 window 对象的集合,window.parent,window.top是对父窗口和顶级窗口的引用,iframe.contentWindow是<iframe>标签内的 window 对象。
如果是同源的话,可以进行操作,不同源的话只能如下
- 更改另一个窗口的
location(只能写入)。 - 向其发送一条消息。
postMessage 接口可以让两个不同源的窗口通讯:
-
发送方调用
targetWin.postMessage(data, targetOrigin)。 -
如果
targetOrigin不是'*',那么浏览器会检查窗口targetWin是否具有源targetOrigin。 -
如果它具有,
targetWin会触发具有特殊的属性的message事件:origin—— 发送方窗口的源(比如http://my.site.com)。source—— 对发送方窗口的引用。data—— 数据,可以是任何对象。但是 IE 浏览器只支持字符串,因此我们需要对复杂的对象调用JSON.stringify方法进行处理,以支持该浏览器。
我们应该使用
addEventListener来在目标窗口中设置message事件的处理程序。