window.postMessage()方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain
设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage()方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
使用
打开窗口
let popup = window.open( process.env.VUE_APP_MEDIAASSET_PATH + '/applicationContent/index', "", "width=1000, height=700, top=30, left=50" )
设置domain
document.domain = process.env.VUE_APP_DOMAIN
说明:双方都要设置;而且如果双方不同源时,一定要设置。
父向子发送
let that = this
this.timer = window.setTimeout(function (params) {
popup.postMessage({
clientId: 'apollo',
templateId: 'game_card'
}, process.env.VUE_APP_MEDIAASSET)
}, 3000)
子接收父
window.addEventListener('message',function(e) {
console.log('---e', e)
if (e.origin === process.env.VUE_APP_MEDIAASSET) {
//操作
that.postSource = e.source
}
});
子向父发送
this.postSource.postMessage(list, process.env.VUE_APP_APOLLO); //反过来向父页面传消息
父接收子
const that = this;
window.addEventListener('message',function(e) {
console.log('e--', e);
if (e.origin === process.env.VUE_APP_APOLLO) {
that.clearTimeout(that.timer)
that.contentList = e.data;
}
});
相关参数设置
VUE_APP_MEDIAASSET_PATH = 'https://web-dev.mamp.xxx.org/edit/index.html#'
VUE_APP_MEDIAASSET = 'https://web-dev.mamp.xxx.org'
VUE_APP_DOMAIN = 'xxx.org'
VUE_APP_APOLLO = 'https://apollo-dev.xxx.org'
注意
1、document.domain设置
两个文档,只有在 document.domain
都被设定为同一个值,表明他们打算协作;或者都没有设定 document.domain
属性并且URL的域是一致的 (如何判断一致),这两种条件下,一个文档才可以去访问另一个文档。如果没有这个特殊的策略,每一个站点都会成为他的子域的 XSS 攻击的对象(例如,https://bugzilla.mozilla.org 可以被来自 https://bug*.bugzilla.mozilla.org 站点的 bug 附件攻击)。
2、message
将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。
在一下几种情况下会报错:
-
Function
objects cannot be duplicated by the structured clone algorithm; attempting to throws aDATA_CLONE_ERR
exception. - Cloning DOM nodes likewise throws a
DATA_CLONE_ERR
exception. - Certain object properties are not preserved:
- The
lastIndex
property ofRegExp
objects is not preserved. - Property descriptors, setters, getters, and similar metadata-like features are not duplicated. For example, if an object is marked readonly with a property descriptor, it will be read/write in the duplicate, since that's the default.
- The prototype chain is not walked or duplicated.
- The