window.postMessage
…
一、window.postMessage
基础语法
1.为什么使用
对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数Document.domain设置为相同的值) 时,这两个脚本才能相互通信。
window.postMessage()
则实现了不同页面脚本的跨域通信
2.语法
2-1 发送
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
, 其他窗口的一个引用- iframe的contentWindow属性
- 执行
window.open
返回的窗口对象 - 命名过或数值索引的window.frames
message
: 要发送到其他 window的数据targetOrigin
: 指定哪些窗口能接收到消息事件, 其值可以是字符串"*"(表示无限制)或者一个URI
2-2 监听接收
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
// 安全:始终使用origin和source属性验证发件人的身份
// 这里不准确,chrome没有这个属性
// var origin = event.origin || event.originalEvent.origin;
var origin = event.origin
if (origin !== "http://example.org:8080")
return;
// ...
}
message
的属性有:
data
: 从其他window
中传递过来的对象origin
: 调用 postMessage 时消息发送方窗口的origin
source
: 对发送消息的窗口对象的引用; 使用此属性可实现不同origin的两个窗口双向通信
二、多场景通信
- 多标签页通信
iframe
嵌套通信
1.多标签页通信
/*
* A窗口的域名是<http://example.com:8080>,以下是A窗口的script标签下的代码:
*/
var popup = window.open(...popup details...);
popup.postMessage("hello there!", "http://example.org");
function receiveMessage(event) {
// 我们能相信信息的发送者吗? (也许这个发送者和我们最初打开的不是同一个页面).
if (event.origin !== "http://example.org")
return;
// event.source 是我们通过window.open打开的弹出页面 popup
// event.data 是 popup发送给当前页面的消息 "hi there yourself! the secret response is: rheeeeet!"
}
window.addEventListener("message", receiveMessage, false);
/*
* 弹出页 popup 域名是<http://example.org>,以下是script标签中的代码:
*/
//当A页面postMessage被调用后,这个function被addEventListener调用
function receiveMessage(event) {
// 验证了所受到信息的origin
if (event.origin !== "http://example.com:8080")
return;
// event.source 就当前弹出页的来源页面
// event.data 是 "hello there!"
// 把event.source作为回信的对象,并且把event.origin作为targetOrigin
event.source.postMessage("hi there yourself! the secret response " + "is: rheeeeet!", event.origin);
}
window.addEventListener("message", receiveMessage, false);
2.iframe
嵌套通信
主应用
<iframe src='https://lianpf.github.io' ref='iframe' id='iframe></iframe>
mounted() {
this.$refs.iframe.contentWindow.postMessage({type:'initData', data: this.date}, this.$refs.iframe.src)
window.addEventListener(
'message',
e => {
// ...
},
false
)
}
iframe
: 地址https://lianpf.github.io
window.parent.postMessage({
type: 'release',
data: {
schema: this.$refs.editor.preview,
staticCode: this.$refs.editor.tempCustomJSCode,
staticCodeUMD: compileCode
}
})
mounted/create () {
window.addEventListener(
'message',
e => {
if(typeof e.data === 'string'){
console.log('传递无效信息')
} else {
if(e.data.type) {
console.log('正常发送数据')
const receiveData = e.data
if (receiveData.type) {
// TODO: 数据分发更新store
handleReceiveData(receiveData, vue)
}
}
}
},
false
)
}
参考
最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~
本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!