postMessage 接口允许窗口之间相互通信,无论它们来自什么源。
因此,这是解决“同源”策略的方式之一。它允许来自于 john-smith.com 的窗口与来自于 gmail.com 的窗口进行通信,并交换信息,但前提是它们双方必须均同意并调用相应的 JavaScript 函数。这可以保护用户的安全。
这个接口有两个部分。
postMessage
想要发送消息的窗口需要调用接收窗口的 postMessage 方法。换句话说,如果我们想把消息发送给 win,我们应该调用 win.postMessage(data, targetOrigin)。
参数:
data
要发送的数据。可以是任何对象,数据会被通过使用“结构化序列化算法(structured serialization algorithm)”进行克隆。IE 浏览器只支持字符串,因此我们需要对复杂的对象调用 JSON.stringify 方法进行处理,以支持该浏览器。
targetOrigin
指定目标窗口的源,以便只有来自给定的源的窗口才能获得该消息。
targetOrigin 是一种安全措施。请记住,如果目标窗口是非同源的,我们无法在发送方窗口读取它的 location。因此,我们无法确定当前在预期的窗口中打开的是哪个网站:用户随时可以导航离开,并且发送方窗口对此一无所知。
指定 targetOrigin 可以确保窗口仅在当前仍处于正确的网站时接收数据。在有敏感数据时,这非常重要。
例如,这里的 win 仅在它拥有来自 http://example.com 这个源的文档时,才会接收消息:
举个例子
结果:
总结
postMessage 接口允许两个具有任何源的窗口之间进行通信:
发送方调用 targetWin.postMessage(data, targetOrigin)。
如果 targetOrigin 不是 ‘*’,那么浏览器会检查窗口 targetWin 是否具有源 targetOrigin。
如果它具有,targetWin 会触发具有特殊的属性的 message 事件:
origin —— 发送方窗口的源(比如 http://my.site.com)。
source —— 对发送方窗口的引用。
data —— 数据,可以是任何对象。但是 IE 浏览器只支持字符串,因此我们需要对复杂的对象调用 JSON.stringify 方法进行处理,以支持该浏览器。
我们应该使用 addEventListener 来在目标窗口中设置 message 事件的处理程序。