postmessage前必须确认目标窗口有效,否则会报typeerror;targetorigin不可设为'*',需严格校验event.origin;消息需带id并设超时,监听器须及时销毁。

postMessage 发送前必须确认目标窗口有效
直接调用 iframe.contentWindow.postMessage() 或 popup.postMessage() 报 TypeError: Cannot read property 'postMessage' of null,基本都是因为目标还没 ready。iframe 没加载完、window.open() 被拦截、sandbox 属性限制了访问权限,都会让 contentWindow 为 null。
- iframe 场景:必须监听
iframe.onload或iframe.addEventListener('load', ...)后再取contentWindow - popup 场景:
window.open()返回值可能为null(弹窗被拦截),需先判空再发消息 - sandbox 场景:若 iframe 含
sandbox="allow-scripts"但不含allow-same-origin,即使同源也无法读取contentWindow,只能靠postMessage单向通信
targetOrigin 写成 '*' 就等于没设防
targetOrigin 参数不是可有可无的装饰项。设成 '*' 表示“发给任意源”,浏览器不会拦,但中间人或恶意页面只要能控制 iframe 加载位置,就能截获消息——尤其在嵌套 iframe 或代理页场景下风险极高。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 生产环境必须写死协议+域名+端口,例如
'https://pay.example.com' - 开发调试时可用
'*'快速验证逻辑,但上线前必须替换 - 如果子页是
http而父页是https,消息会被浏览器静默丢弃(协议不一致)
message 监听器里不校验 event.origin 就是 XSS 温床
只写 window.addEventListener('message', handler) 是危险的起点。任何网站只要知道你的页面 URL,就能用 window.open() 或 iframe 嵌入后发消息,触发你监听器里的任意逻辑。
- 必须严格比对
event.origin === 'https://expected.com',不能只检查 hostname - 不要用
event.source做权限判断——它可被伪造,仅适合回传响应 - 建议加一层数据结构校验,比如
typeof event.data === 'object' && 'type' in event.data,避免undefined访问报错
需要响应就自己管 ID 和超时,postMessage 本身不支持回调
postMessage 是纯单向、无 ACK 的机制。你发了 { type: 'GET_USER' },对方收到后调用 event.source.postMessage() 回传,但你根本不知道这消息是否发出、是否送达、是否被处理——更别说超时重试或取消。
- 约定消息带
id字段(如Math.random().toString(36).substr(2, 9)),接收方回传时带上相同id - 发送方用
setTimeout设超时,未收到响应则清理 pending 请求 - 监听器销毁前记得
removeEventListener,否则挂起的响应可能触发已卸载组件的错误
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










