跨域iframe通信报错:Uncaught TypeError: Cannot read properties of null (reading 'postMessage')
问题分析与解决
报错说明
原报错Uncaught TypeError: Cannot read properties of null (reading 'postMessage')翻译为:未捕获的类型错误:无法读取null的属性(读取'postMessage')
核心问题拆解
出现该错误的直接原因有两个:
- 脚本执行时机过早:主站脚本写在iframe元素之前,DOM还未渲染出目标元素,
document.getElementById返回null,调用postMessage自然报错。 - 元素选择错误:你选中的是iframe的容器div(
secondSiteContainer),而非iframe本身,div元素没有postMessage方法。
此外还有两处跨域逻辑疏漏:
- 子站校验主站域名时缺少协议(应为
http://mainwebsite.com而非mainsite.com),会导致合法消息被拦截。 - 主站未实现接收子站高度消息并调整iframe的逻辑,无法解决滚动问题。
修复后的完整代码
主站(Mainwebsite.com)
<div class="grid grid-col-12" id="secondSiteContainer"> <iframe src="http://secondsite.com" title="description" width="100%" id="myIframe" style="height: 1700px; border: none;"> </iframe> </div> <script type="text/javascript"> // 等待DOM完全加载后执行逻辑 window.addEventListener('DOMContentLoaded', () => { const iframe = document.getElementById('myIframe'); // 监听子站发来的消息 window.addEventListener('message', (event) => { // 严格校验消息来源,防止恶意请求 if (event.origin !== "http://secondsite.com") return; // 接收子站页面高度,动态调整iframe高度 if (typeof event.data === 'number') { iframe.style.height = `${event.data}px`; } }, false); // 等iframe加载完成后,发送消息触发子站计算高度 iframe.addEventListener('load', () => { iframe.contentWindow.postMessage('get-height', 'http://secondsite.com'); }); }); </script>
子站(Secondsite.com)
$(document).ready(function() { window.addEventListener("message", (event) => { // 校验主站域名,必须与主站地址完全匹配(包含协议) if (event.origin !== "http://mainwebsite.com") return; // 计算当前页面的实际高度(兼容不同浏览器) const pageHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); // 将高度发送回主站 event.source.postMessage(pageHeight, event.origin); }); });
关键修复点说明
- 调整脚本执行时机:通过
DOMContentLoaded事件确保DOM渲染完成后再获取元素,或把脚本放在iframe元素之后。 - 正确选择目标元素:通过iframe的id
myIframe获取元素,调用其contentWindow.postMessage方法发送跨域消息。 - 严格跨域校验:主站和子站的域名校验必须完全一致(包含http/https协议),避免合法消息被拦截。
- 实现高度同步逻辑:子站计算自身页面实际高度并发送给主站,主站接收后动态设置iframe高度,解决滚动问题。
内容的提问来源于stack exchange,提问作者woninana
相关产品推荐
相关产品推荐

