父頁面打開彈出窗口後立即調用 postMessage 發送數據,但子窗口只有極小概率能收到消息,大多數情況下丟失。
競態條件:父頁面發送消息時,子窗口的 message 事件監聽器尚未註冊完成。子窗口加載過程中,腳本執行順序導致監聽器註冊滯後於父頁面發送動作。
<head> 中提前註冊監聽器(推薦)<head>
<script>
function receiveMessage(event) {
// 處理 event.data
}
window.addEventListener("message", receiveMessage, false);
</script>
</head>
確保監聽器在頁面解析階段就已就緒,早於任何外部消息到達。
setTimeout(function() {
popupWindow.postMessage(data, targetOrigin);
}, 1000); // 網速慢時可能仍失效
message 監聽器。{type: 'ready'} 消息。// 父頁面
window.addEventListener("message", function(e) {
if (e.data.type === 'ready') {
popupWindow.postMessage(businessData, targetOrigin);
}
});
// 子窗口
window.addEventListener("load", function() {
window.opener.postMessage({type: 'ready'}, '*');
});
方案一最簡單有效,方案三適合複雜交互場景。切勿依賴固定延時。