Iframe 父子页面消息传递实战
iframe postMessage Vue Routeriframe 可在当前页面内嵌独立子应用,父子页面可分别使用不同技术栈,只要约定好消息格式即可协作。本文记录一次实际踩坑:父页面嵌入使用 Vue Router Hash 路由的子应用,浏览与后退正常,但刷新后子路由丢失、回到首页。下文给出背景、方案与完整实现。
背景
进入首页后,依次点击 Go to Apple、Go to Banana、Go to Orange,下方路由会正确渲染,浏览器后退也正常。停留在 Orange 路由并刷新页面时,iframe 内的路由状态丢失,被重置为首页。

目标:刷新后子页面路由保持原有状态。
方案
整体流程可概括为「子页上报 → 父页缓存 → 刷新后下发 → 子页恢复」:
- 子页面监听路由变化,通过
postMessage通知父页面 - 父页面接收消息,将路由写入
localStorage - 页面刷新后,父页面在
iframe加载完成时读取缓存 - 父页面将缓存路由
postMessage给子页面 - 子页面监听消息,执行
router.push跳转到对应路由
实现
父页面
父页面负责两件事:接收子页面的路由更新并持久化,以及在 iframe 就绪后把缓存路由发回子页面。
子页面
子页面使用 Vue 3 + Vue Router(Hash 模式)。在 beforeEach 里上报路由,并监听父页面下发的恢复消息。
注意点
postMessage的targetOrigin:示例写死了http://localhost:3000,生产环境应换成实际域名,并在message事件里校验e.origin,避免恶意页面注入消息。- 恢复后清除缓存:父页面下发路由后会
removeItem,防止每次iframe重载都重复跳转。 - 首页不上报:子页面在
fullPath === "/"时跳过上报,否则刷新后可能把有效路由覆盖成首页。 - 时序依赖:恢复逻辑放在
iframe.onload中,确保子页面脚本已加载、能接收消息。若子应用初始化较慢,可在子页面主动postMessage告知「已就绪」,再由父页面下发缓存。
小结
通过 postMessage 在父子页面间同步路由,并由父页面用 localStorage 持久化,即可在刷新后恢复 iframe 内子应用的路由状态。完整可运行示例见 GitHub。