父页面通过iframe向子页面postMessage无响应,请求排查问题
问题分析与解决
你的代码存在两个核心问题,导致iframe无法接收并响应消息:
1. 消息发送时机过早
父页面脚本在DOM加载完成后立即调用postMessage,但此时iframe的child.html还未加载完毕,子页面的消息监听器尚未初始化,自然接收不到消息。
2. 子页面Origin验证逻辑错误
event.origin返回的是发送消息页面的实际源(比如你的案例中是https://rossewij.nl),而你写的判断条件是event.origin === '*',两者完全不匹配,导致验证失败,直接执行错误分支的代码。
修正后的代码
父页面(parent.html)
添加iframe的load事件监听,确保子页面加载完成后再发送消息:
<!-- parent.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Parent Page</title> </head> <body> <h1>Parent Page</h1> <iframe id="myIframe" src="child.html" width="400" height="300"></iframe> <script> const iframe = document.getElementById('myIframe'); const dataToSend = { message: 'Hello from parent!', someValue: 42 }; // 等待iframe加载完成后再发送消息 iframe.addEventListener('load', () => { // 生产环境建议替换*为实际子页面源,提升安全性 iframe.contentWindow.postMessage(dataToSend, '*'); }); </script> </body> </html>
子页面(child.html)
修正origin验证逻辑,匹配实际父页面源(或调试阶段暂时跳过验证,生产环境必须严格校验):
<!-- child.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Child Page</title> </head> <body> <h1>Child</h1> <script> window.addEventListener('message', (event) => { // 生产环境请替换为实际父页面源,比如'https://rossewij.nl' // if (event.origin === 'https://rossewij.nl') { // 调试阶段可先跳过验证(不推荐生产环境使用) if (true) { const receivedData = event.data; console.log(receivedData.message); console.log(receivedData.someValue); // 可将内容显示在页面上,方便直观查看 document.body.innerHTML += `<p>收到父消息:${receivedData.message}</p>`; document.body.innerHTML += `<p>收到数值:${receivedData.someValue}</p>`; } else { console.log("非可信来源的消息,已拒绝"); } }); </script> </body> </html>
安全提示
生产环境中,postMessage的第二个参数(目标源)绝对不要用*,需指定明确的可信源;同时子页面的event.origin验证要严格匹配父页面源,避免跨域消息劫持风险。
内容的提问来源于stack exchange,提问作者Arjan R
相关产品推荐
相关产品推荐

