一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

HTML内联框架标签如何通过postMessage实现父子页面通信

时间:2026-09-03 17:49:47 编辑:袖梨 来源:一聚教程网

postMessage 实现父子页面通信的关键在于精准发送、稳定接收和严格校验:父页需等待 iframe 加载完成、校验 contentWindow 并指定完整 targetOrigin;子页必须首验 event.origin 且用严格相等比对,再解析 event.data;回传可用 "*",但需闭环响应;移动端需绑定用户手势触发 play()。

用 `

父页向子页发消息:先取窗口、再等加载、最后精准投递

父页不能一加载完就立刻调用 `postMessage`,必须确保 iframe 已完成加载且 `contentWindow` 可用。否则会报错或静默失败。

  1. 用 `iframe.onload` 或 `iframe.addEventListener('load')` 监听加载完成事件
  2. 获取子页窗口对象:`const childWin = iframe.contentWindow`,使用前加空值判断(如 `if (!childWin) return`)
  3. 发送时 `targetOrigin` 必须写成子页**完整源地址**,例如 https://player.example.com:8080;填 "*" 在生产环境会被浏览器丢弃,且无错误提示
  4. 推荐结构化数据,如 { type: "play", time: 32 },避免字符串解析歧义

子页接收消息:第一件事是验 origin,不是解 data

子页监听 `message` 事件后,必须第一时间校验 `event.origin`。未校验就执行操作(比如 `video.play()` 或跳转),等于把控制权交给任意 。

  1. 用严格相等 === 比对,禁止 `includes()` 或 `indexOf()` —— 否则会被 https://evil-example.com 绕过
  2. 白名单写死:例如 if (event.origin !== 'https://shop.example.com') return;
  3. 多个合法源可显式判断:['https://a.com', 'https://b.com'].includes(event.origin)
  4. 解析 event.data 前先做类型检查,防止 undefined 或非对象导致脚本中断

子页回传消息:可用 "*",但逻辑要闭环

子页调用 window.parent.postMessage() 向父页反馈状态时,targetOrigin 可设为 "*",因为父页源不可预知且已控制 iframe 加载行为,风险相对可控。

  1. 常见回传内容:播放进度、错误码、加载完成信号(如 { type: "ready", canPlay: true }
  2. 父页收到后应做对应响应,比如更新 UI 或触发下一步动作
  3. 建议建立简单协议:子页首次加载后主动发 { type: "init" },父页再发控制指令,避免竞态

移动端特别注意:play() 必须绑定用户手势

iOS 和 Android 要求 `video.play()` 必须由用户真实交互(click/touchstart)触发。通过 `postMessage` 发来的指令属于程序调用,直接执行大概率抛 NotAllowedError

  1. 子页应在 video 元素上绑定一次用户手势,在回调中调用 play() 并返回 Promise
  2. 后续所有 `postMessage` 指令(seek、pause 等)都等该 Promise settled 后再执行
  3. 父页可先发 { type: "check-ready" } 探测子页是否已准备好接受控制

热门栏目