跨窗口通信唯一安全方式是window.postMessage(),需指定目标窗口并校验event.origin,禁止用*通配targetOrigin,不支持传函数或DOM节点,须实测边界场景。

跨窗口通信在 HTML 中本质是受限的,但通过 window.postMessage() 可以安全、可控地实现。直接访问 window.opener 或 window.frames 在跨源时会触发 SecurityError,这不是 bug,而是浏览器强制策略——所以别试图绕过同源限制,该用 postMessage 就用。
postMessage 是唯一通用且安全的跨窗口通信方式
它支持任意源(targetOrigin 可设为 '*',但不推荐),能传基本类型、对象(需可序列化)、ArrayBuffer 等。关键点在于:发送方必须指定目标窗口引用(如 popup 或 iframe.contentWindow),接收方必须校验 event.origin 防止伪造消息。
- 不校验
event.origin→ 任何网站都能向你的页面发消息,可能触发逻辑误执行 - 把
targetOrigin写成'*'→ 消息可能被中间人劫持到非预期源(尤其在 iframe 场景) - 传函数或 DOM 节点 → 会静默失败,
postMessage只序列化,不传引用
示例(主窗口发):
const popup = window.open('child.html', '_blank');<br>popup.postMessage({ type: 'INIT', data: { id: 123 } }, 'https://example.com');
子窗口收:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
iframeEl.contentWindow
- iframe 加载完成前调用
contentWindow.postMessage→ 报错TypeError: Cannot read property 'postMessage' of null,应监听load事件后再发 - 用
window.open打开的页面若被弹窗拦截(如用户禁用弹窗),返回值是null,需判空 - iframe 的
sandbox属性若含allow-scripts但不含allow-same-origin,则即使同源也无法直接访问contentWindow,只能靠postMessage
跨窗口通信不是实时 RPC,要自己处理响应与超时
postMessage 是单向、无返回值的。如果需要“请求-响应”,得手动约定消息 ID、加回调标识、设定时器清理挂起请求。否则容易出现:发了请求,对方没回,你一直等;或对方回了,你监听器已销毁,消息丢失。
- 不要在
message监听器里直接调用异步操作后返回结果——没有返回通道 - 建议用
Map缓存待响应的messageId,配合Promise+setTimeout实现带超时的请求 - 消息体中必须带
id字段,响应消息也带相同id和type: 'RESPONSE'标识,避免混淆
一个最小响应模式示意:
// 发送方<br>const id = Date.now().toString();<br>const p = new Promise((resolve, reject) => {<br> const timeout = setTimeout(() => reject(new Error('timeout')), 5000);<br> const handler = (e) => {<br> if (e.data.id === id && e.data.type === 'RESPONSE') {<br> clearTimeout(timeout);<br> window.removeEventListener('message', handler);<br> resolve(e.data.payload);<br> }<br> };<br> window.addEventListener('message', handler);<br>});<br>targetWindow.postMessage({ type: 'GET_USER', id, payload: {} }, targetOrigin);
真正麻烦的从来不是怎么发消息,而是谁在什么时候监听、是否清理了监听器、源是否可信、消息是否重复或乱序——这些不会报错,但会让调试变成猜谜。写完通信逻辑后,务必在跨域、关闭窗口、快速连续操作等边界场景下实测。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










