如果你有使用iframe,那么肯定使用过或听过postMessage。这个API并没什么难度可言,就是一般很少使用,等到需要用时又容易忘记怎么使用,在此做个备忘吧。
语法
otherWindow.postWindow(message, targetOrigin, [transfer])
- otherWindow: 其他窗口的引用
- message:发送的数据
- targetOrigin:通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串" * "(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的origin属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
以下为代码示例
父窗口文件:iframe_parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<h6>父窗口</h6>
<div>
<input id="input" type="text">
<button id="send">发消息给子窗口</button>
</div>
<p>子窗口的消息:<span id="message"></span></p>
<br>
<iframe id="iframe" src="iframe_child.html" frameborder="1"></iframe>
<script>
const $ = (s) => {return document.querySelector(s)}
const btn = $('#send')
const input = $('#input')
const message = $('#message')
const iframe = $('#iframe')
btn.onclick = () => {
const data = input.value
data && sendMessage(data)
}
function sendMessage(data) {
iframe && iframe.contentWindow.postMessage(data)
}
window.addEventListener('message', (event) => {
message.innerHTML = event.data
// 此处不能再给子窗口发消息,不然会死循环
// event.source.postMessage(`收到${event.data}了`)
})
</script>
</body>
</html>
子窗口文件 iframe_child.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
body{
background: #eee;
}
</style>
</head>
<body>
<h6>子窗口</h6>
<div>
<input id="input" type="text">
<button id="send">发消息给父窗口</button>
</div>
<p>
父窗口的消息: <span id="message"></span>
</p>
<script>
const $ = (s) => {return document.querySelector(s)}
const btn = $('#send')
const input = $('#input')
const message = $('#message')
const parent = window.parent
btn.onclick = () => {
const data = input.value
data && sendMessageToParent(data)
}
window.addEventListener('message', (event) => {
console.log('父窗口===', event.source)
console.log('来自父窗口的消息===', event.data)
message.innerHTML = event.data
event.source.postMessage(`收到(${event.data})了`)
})
function sendMessageToParent (data) {
parent && parent.postMessage(data)
}
</script>
</body>
</html>
遇到报错:Failed to execute ‘postMessage’ on ‘DOMWindow’: The target origin provided (‘https://aaa.com’) does not match the recipient window’s origin (‘https://bbb.com’).
- 解决方法:在postMessage 方法里添加参数 “*”(假如没有安全性要求不高的话)
- 参考:https://stackoverflow.com/questions/27573017/failed-to-execute-postmessage-on-domwindow-https-www-youtube-com-http
参考
- window.postMessage:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage