基本使用:
otherWindow.postMessage(message, targetOrigin, [transfer]);
- otherWindow:待接收发送消息的窗口对象,如iframe.contentWindow、window.open返回的窗口对象、window.parent、window.top、window.opener等,即发送需要获取接收方的 window 对象
- 发送到对应窗口的数据,内容将会结构化克隆算法,这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化.
- targetOrigin:发送窗口的url、或通配符"*“可发送到任意窗口、发送到与当前窗口同源的窗口可设置为”/"
- transfer:是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权,详情
window.addEventListener(“message”, 监听回调fn, false) ;
event
- data : 指的是从其他窗口发送过来的消息对象;
- type: 指的是发送消息的类型;
- source: 指的是发送消息的窗口对象;
- origin: 指的是发送消息的窗口的源
window.open打开的窗口中使用:
<h1>这是 T1</h1>
<button id="btn1">打开t2</button>
<button id="btn2">发送消息到t2</button>
<pre id="text"></pre>
<script>
var t2
var btn1 = document.getElementById('btn1')
var btn2 = document.getElementById('btn2')
var text = document.getElementById('text')
btn1.addEventListener('click', function() {
t2 = window.open('/t2.html')
//等到发送窗口页面加载完成后才发送消息,否则监听不到
t2.window.addEventListener('load', function() {
btn2.click()
})
})
btn2.addEventListener('click', function() {
console.log('btn2 点击');
t2.postMessage({type: 'popring', message: 't1 发送出去的消息'}, '/')
})
window.addEventListener('message', function(event) {
// 过滤非当前域下的消息
if(event.origin !== 'http://127.0.0.1:5500' || !event.data) {
return
}
// 过滤其他非本应用传递过来的消息,例如 chrome 的插件就可能也会发送消息(表示 wappalyzer 就会)
if(event.data?.type !== 'popring') {
return
}
text.innerText += (JSON.stringify(event.data)+'\n')
})
</script>
<h1>这是 T2</h1>
<button id="btn">发送消息到 t1</button>
<pre id="text"></pre>
<script>
var btn = document.querySelector('#btn')
var text = document.getElementById('text')
var t1
// t2 定义的 onload 事件
window.onload = function() {
console.log('t2 onload');
}
btn.addEventListener('click', function() {
t1.postMessage({type: 'popring', message: 't2 发送出去的消息'}, '/')
})
window.addEventListener('message', function(event) {
if(event.origin !== 'http://127.0.0.1:5500' || !event.data) {
return
}
if(event.data?.type !== 'popring') {
return
}
t1 = event.source
text.innerText += (JSON.stringify(event.data)+'\n')
})
</script>
iframe中使用:
const iFrame = document.getElementById('iframe')
<!-- 需要等到iframe中的子页面加载完成后才发送消息,否则子页面接收不到消息 -->
iFrame.onload = function(){
<!-- iFrame.contentWindow获取到iframe的window对象 -->
iFrame.contentWindow.postMessage('父页面发送的消息','http://b.index.com');
}
window.addEventListener('message',e=>{
<!-- 对消息来源origin做一下过滤,避免接收到非法域名的消息导致的xss攻击 -->
if(e.origin==='http://b.index.com'){
console.log(e.origin) //子页面URL,这里是http://b.index.com
console.log(e.source) // 子页面window对象,全等于iframe.contentWindow
console.log(e.data) //子页面发送的消息
}
},false)
子页面接收
window.addEventListener('message',e=>{
<!-- 对消息来源origin做一下过滤,避免接收到非法域名的消息导致的xss攻击 -->
if(e.origin==='http://a.index.com'){
console.log(e.origin) //父页面URL,这里是http://a.index.com
console.log(e.source) // 父页面window对象,全等于window.parent/window.top
console.log(e.data) //父页面发送的消息
}
},false)
//子页面发送给父窗口
window.parent.postMessage('子页面发送的消息','http://a.index.com')