在线演示
在这里您可以直观地体验 postmessage-duplex 的功能,无需安装任何依赖。
交互式 Playground
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 集成 - 框架集成示例