postmessage-duplexpostmessage-duplex
首页
指南
API
示例
🎮 Playground
  • FAQ
  • 更新日志
  • GitHub
  • 简体中文
  • English
GitHub
首页
指南
API
示例
🎮 Playground
  • FAQ
  • 更新日志
  • GitHub
  • 简体中文
  • English
GitHub

在线演示

在这里您可以直观地体验 postmessage-duplex 的功能,无需安装任何依赖。

交互式 Playground

🖼️ Iframe 示例 🖼️ Iframe 多页面示例 ⚙️ Service Worker 示例 📡 SW 多页面通讯示例

Iframe Playground

体验父页面与 iframe 子页面之间的双向通讯:

  • ✅ 发送消息 - 从父页面向子页面发送消息
  • ✅ 请求数据 - 体验请求-响应模式
  • ✅ 测试超时 - 观察超时处理机制
  • ✅ 查看日志 - 实时查看通讯过程
  • ✅ 双向通讯 - 子页面也可以向父页面发送消息

Iframe 多页面 Playground

体验父页面作为 Hub 管理多个子 iframe 的通讯场景:

  • ✅ 多 iframe 管理 - 父页面作为 Hub 管理多个子 iframe
  • ✅ 点对点通讯 - 父页面与子页面双向请求-响应
  • ✅ 子页面间通讯 - 子页面 A → 父页面(Hub) → 子页面 B
  • ✅ 广播通讯 - 父页面向所有/指定类型子页面广播
  • ✅ iframe 刷新处理 - 子 iframe 重新加载后自动重建连接

Service Worker Playground

体验页面与 Service Worker 之间的双向通讯:

  • ✅ 注册/注销 SW - 管理 Service Worker 生命周期
  • ✅ Ping 测试 - 测量通讯延迟
  • ✅ 数据请求 - 从 SW 获取数据
  • ✅ Echo 回显 - 验证消息往返
  • ✅ 错误处理 - 观察错误响应
  • ✅ 超时机制 - 测试请求超时

SW 多页面通讯 Playground

体验一个 Service Worker 同时与多个应用页面通讯的场景:

  • ✅ 多客户端连接 - 两个独立应用同时连接同一个 SW
  • ✅ 消息广播 - 从任一应用向所有其他应用广播消息
  • ✅ 独立业务处理 - 每个应用有独立的业务功能(购物车/用户中心)
  • ✅ 实时通讯日志 - 观察多页面间的消息流转
  • ✅ iframe 嵌入展示 - 在文档页面中同时展示两个应用

快速体验

场景 1:简单消息传递

父页面发送消息:

// 创建通道
const channel = new IframeChannel(iframe)

// 发送消息并等待响应
const response = await channel.publish('greeting', { 
  message: 'Hello!' 
})

console.log(response.data)
// { reply: 'Hello from child!', originalMessage: 'Hello!' }

子页面接收并响应:

// 创建通道
const channel = new IframeChannel(parentOrigin)

// 监听消息
channel.subscribe('greeting', ({ data }) => {
  console.log('收到:', data.message)
  
  // 返回响应
  return { 
    reply: 'Hello from child!',
    originalMessage: data.message 
  }
})

场景 2:请求数据

父页面请求数据:

// 请求用户信息
const response = await channel.publish('getUserInfo', { 
  userId: 123 
})

if (response.ret === ReturnCode.Success) {
  console.log('用户信息:', response.data)
  // { id: 123, name: 'John', email: 'john@example.com' }
}

子页面处理请求:

channel.subscribe('getUserInfo', async ({ data }) => {
  // 从数据库获取用户
  const user = await fetchUser(data.userId)
  
  // 返回用户信息
  return user
})

场景 3:双向通讯

// 父页面监听子页面通知
channel.subscribe('notification', ({ data }) => {
  showToast(data.message)
  return { received: true }
})

// 子页面主动发送通知
channel.publish('notification', { 
  type: 'success',
  message: '操作完成!' 
})

在本地运行 Demo

# 克隆仓库
git clone https://github.com/ljquan/postmessage-duplex.git
cd postmessage-duplex

# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 访问 Demo
open http://localhost:7100/demo/

Demo 目录结构

demo/
├── iframe/              # iframe 通讯示例
│   ├── index.html       # 父页面
│   └── child.html       # 子页面
├── service-worker/      # Service Worker 示例
│   ├── index.html       # 主页面
│   └── sw.js            # Service Worker
└── debugger/            # 调试工具
    ├── index.html       # 调试器主页
    └── child.html       # 被调试页面

代码示例

完整的父页面代码

<!DOCTYPE html>
<html>
<head>
  <title>父页面</title>
</head>
<body>
  <iframe id="child" src="./child.html"></iframe>
  <button id="sendBtn">发送消息</button>
  
  <script type="module">
    import { IframeChannel, ReturnCode } from 'postmessage-duplex'
    
    const iframe = document.getElementById('child')
    const channel = new IframeChannel(iframe)
    
    // 监听子页面消息
    channel.subscribe('notification', ({ data }) => {
      console.log('收到通知:', data)
      return { acknowledged: true }
    })
    
    // 发送消息
    document.getElementById('sendBtn').onclick = async () => {
      const response = await channel.publish('getData', { id: 1 })
      
      if (response.ret === ReturnCode.Success) {
        console.log('数据:', response.data)
      } else {
        console.error('错误:', response.msg)
      }
    }
    
    // 清理
    window.onbeforeunload = () => channel.destroy()
  </script>
</body>
</html>

完整的子页面代码

<!DOCTYPE html>
<html>
<head>
  <title>子页面</title>
</head>
<body>
  <button id="notifyBtn">通知父页面</button>
  
  <script type="module">
    import { IframeChannel } from 'postmessage-duplex'
    
    // 传入父页面 origin
    const channel = new IframeChannel(window.location.origin)
    
    // 处理数据请求
    channel.subscribe('getData', ({ data }) => {
      return {
        id: data.id,
        name: 'Item ' + data.id,
        price: 99.99
      }
    })
    
    // 发送通知
    document.getElementById('notifyBtn').onclick = async () => {
      await channel.publish('notification', {
        type: 'info',
        message: 'Hello from child!'
      })
    }
  </script>
</body>
</html>

下一步

  • 快速开始 - 详细的入门指南
  • API 文档 - 完整的 API 参考
  • Vue/React 集成 - 框架集成示例
在 GitHub 上编辑此页
上次更新: 2026/1/31 05:17
贡献者: liquidliang, liquid, Claude