在項目中可能會通過iframe直接将另一個頁面嵌入進來,某些場景下還可能會進行一些消息的傳遞通信。之前做過一次,就是我們開發的主系統,然後下面還有很多子系統,子系統都是通過iframe嵌入進來的,然後為了實作某些需求,需要将token傳遞給子系統,拱子系統使用,但是當時一直忙着開發,忘記記錄了,是以這篇算是補上吧
嵌入進來的頁面的window跟我們現在的window已經不是同一個了,更不是同一個document。
然後跨域通信的話,父視窗向子視窗我們通過 iframe.contentWindow.postMessage 發送消息;子視窗向父視窗我們通過 window.parent.postMessage 發送消息;然後接受的話都是監聽window的message事件,如下:
otherWindow.postMessage(message, targetOrigin, [transfer]);
- message
是我們發送的資訊,一般我會傳個JSON,也可以是個對象、字元串。。
- targetOrigin
父視窗向子視窗發送消息
iframe.contentWindow.postMessage(JSON.stringify({
type: 'www',
ctx: '給你消息,收到了嘛?'
}), '*')
子視窗向父視窗發送消息
window.parent.postMessage(JSON.stringify({
type: 'yes',
ctx: '我收到您發送的消息了!'
}), '*')
接受消息
// 接受消息
window.addEventListener('message', receiveMessage, false)
function receiveMessage(event) {
const msg = JSON.parse(event.data)
console.log(msg, '----->>>')
}
測試的完整代碼
父視窗
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.content {
width: 100vw;
height: 100vh;
position: relative;
}
.content button {
position: absolute;
top: 150px;
left: 50%;
transform: translateX(-50%);
}
.iframe {
width: 500px;
height: 500px;
border: 1px solid #ccc;
border-radius: 6px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<div class="content">
<button id="btn">SEND</button>
<div class="iframe">
<iframe id="my-iframe" src="./iframe.html" style="width: 100%;height: 100%;" frameborder="0"></iframe>
</div>
</div>
<script>
const $ = name => document.querySelector(name)
// 發送消息到子視窗
$('#btn').onclick = function(e) {
$('#my-iframe').contentWindow.postMessage(JSON.stringify({
type: 'www',
ctx: '給你消息,收到了嘛?'
}), '*')
}
// 接受子視窗的消息
window.addEventListener('message', receiveMessage, false)
function receiveMessage(event) {
const msg = JSON.parse(event.data)
console.log(msg, '----->>>')
}
</script>
</body>
</html>
子視窗 (iframe.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.iframe-content {
width: 100vw;
height: 100vh;
background-color: #f5f5f5;
text-align: center;
line-height: 100vh;
}
</style>
<div class="iframe-content">
<span>我是Iframe</span>
<button id="iframe-btn">SEND</button>
</div>
<script>
// 接受父視窗的消息
window.addEventListener('message', receiveMessage, false)
function receiveMessage(event) {
const msg = JSON.parse(event.data)
console.log(msg, '----->>>')
}
// 10s後發送消息到父視窗
setTimeout(() => {
window.parent.postMessage(JSON.stringify({
type: 'yes',
ctx: '我收到您發送的消息了!'
}), '*')
}, 5000)
</script>
</body>
</html>