如何用window.postMessage实现后端向前端传数据?解决相关报错
解决window.postMessage跨域及window.opener为null的问题
第一个报错:target origin不匹配
原因
浏览器把http://localhost:8000和http://127.0.0.1:5173视为两个完全独立的源,postMessage要求传入的targetOrigin必须和目标窗口的实际origin完全一致,否则就会触发该错误。
解决方法
- 统一访问域名/IP
将两个页面的访问地址统一为同一个域名或IP,比如前端和后端都用localhost:前端服务启动在localhost:5173,后端服务用localhost:8000,然后把postMessage的targetOrigin设为目标窗口的准确origin(比如向前端传数据就设'http://localhost:5173')。 - 正确设置targetOrigin参数
开发环境下如果不确定目标origin,可以临时用'*'(仅限开发,生产环境绝对禁止,存在安全风险):
生产环境必须明确指定目标窗口的准确origin:window.postMessage(你的数据, '*');window.postMessage(你的数据, 'http://localhost:5173');
第二个报错:window.opener为null
原因
window.opener只有在当前窗口是被另一个窗口通过window.open()方法打开时才会有值,若不是通过这种方式打开的窗口,直接调用window.opener.postMessage必然会报null错误。
解决方法
- 确保窗口通过window.open打开
如果是主窗口给子窗口发消息,先通过window.open打开子窗口并保存引用,等子窗口加载完成后再发送消息:
如果是子窗口给主窗口发消息,需保证子窗口是被主窗口用// 主窗口代码 const childWin = window.open('http://localhost:5173'); childWin.onload = () => { childWin.postMessage(你的数据, 'http://localhost:5173'); };window.open打开的,此时window.opener才会指向主窗口,建议先做判断避免报错:// 子窗口代码 if (window.opener) { window.opener.postMessage(你的数据, 'http://localhost:8000'); } - 更换数据传递方式(无法使用window.open时)
- 同域场景:使用
localStorage或sessionStorage,配合storage事件监听:// 发送方 localStorage.setItem('sharedData', JSON.stringify(你的数据)); // 接收方 window.addEventListener('storage', (e) => { if (e.key === 'sharedData') { const data = JSON.parse(e.newValue); // 处理数据 } }); - 跨域场景:通过后端中转数据,发送方把数据传给后端,接收方从后端接口拉取数据。
- 同域场景:使用
必加的安全验证
接收消息的窗口必须监听message事件,且生产环境一定要验证event.origin,防止恶意网站发送的消息:
window.addEventListener('message', (event) => { // 只处理指定origin的消息 if (event.origin === 'http://localhost:8000') { const receivedData = event.data; // 处理你的数据 } });
内容的提问来源于stack exchange,提问作者Zos
相关产品推荐
相关产品推荐

