一个 简单、轻量、专注通信 的 JavaScript / TypeScript 库,用于 iframe 跨域消息传递。
本库专注于 纯通信功能,不包含 iframe 创建和管理。用户需要自行创建 iframe,只需传入 window 对象即可开始通信。
- 🚀 轻量无依赖 - 仅专注于 postMessage 通信
- 🔌 即插即用 - 支持传入 iframe DOM 或 window 对象
- 🛡️ 类型安全 - 完整的 TypeScript 类型支持
- 💬 双向通信 - 父页面与子页面自由对话
- 🎯 安全验证 - 支持 origin + source 校验
- 🤝 握手协议 - 内置 READY / ACK,确保通信可靠
- 🧩 命名空间隔离 - 避免多实例/多应用消息冲突
- 📦 简单易用 - API 简洁直观
我们提供了一个功能完整的在线演示页面,您可以直接在浏览器中体验所有功能:
🌐 立即体验: 点击访问在线演示
pnpm install @giszhc/iframe-client
# 或
npm install @giszhc/iframe-client
yarn add @giszhc/iframe-client本库内置 握手协议(Handshake),确保双方建立连接后再通信。
child → READY
parent → ACK
→ connected = true
❗ 必须在 onConnect 后发送消息
const client = new IframeClient({
type: 'parent',
iframe,
namespace: 'my-app:demo:v1',
onConnect: () => {
// ✅ 正确
client.sendMessage('INIT', {});
}
});所有消息会被统一封装为:
{
__iframe_client__: true,
namespace: string,
type: string,
payload?: any
}import { IframeClient } from '@giszhc/iframe-client';
// 获取 iframe DOM 元素
const iframe = document.getElementById('myIframe') as HTMLIFrameElement;
const client = new IframeClient({
type: 'parent', // 指定当前角色为父页面
iframe, // 传入 iframe DOM 元素
targetOrigin: 'http://localhost:3001', // 子页面的目标源地址(生产环境请指定具体域名)
namespace: 'my-app:demo:v1', // 命名空间,用于消息隔离(格式建议:应用名:功能:版本)
// 连接成功后的回调函数(握手完成后触发)
onConnect: () => {
console.log('✅ 已连接 iframe');
// 发送初始化消息,包含用户 ID
client.sendMessage('INIT', { id: 123 });
}
});
// 监听来自子页面的 RESPONSE 类型消息
client.on('RESPONSE', (data) => {
console.log('收到响应:', data);
});import { IframeClient } from '@giszhc/iframe-client';
const client = new IframeClient({
type: 'child', // 指定当前角色为子页面(iframe 内)
targetWindow: window.parent, // 指定目标窗口为父窗口
targetOrigin: 'http://localhost:3000', // 父页面的源地址(生产环境请指定具体域名)
namespace: 'my-app:demo:v1', // 命名空间,必须与父页面保持一致
// 连接成功后的回调函数(握手完成后触发)
onConnect: () => {
console.log('✅ 已连接父页面');
}
});
// 监听来自父页面的 INIT 类型消息
client.on('INIT', (data) => {
console.log('收到:', data);
// 发送响应消息给父页面
client.sendMessage('RESPONSE', { ok: true });
});interface IframeClientConfig {
type: 'parent' | 'child';
iframe?: HTMLIFrameElement;
targetWindow?: Window;
targetOrigin?: string;
namespace: string;
onConnect?: () => void;
onError?: (error: Error) => void;
}client.sendMessage('EVENT', { data: 1 });client.on('EVENT', (data, event) => {
console.log(data);
});client.off('EVENT', handler);client.destroy();client.isConnected();【握手阶段】
child → READY
parent → ACK
【业务通信】
parent → INIT
child → RESPONSE
// ❌ 错误
namespace: 'a'
namespace: 'b'
// ✅ 正确
namespace: 'my-app:demo:v1'// ❌ 错误
client.sendMessage('INIT');
// ✅ 正确
onConnect: () => {
client.sendMessage('INIT');
}// parent
new IframeClient({
type: 'parent',
iframe,
namespace: 'xxx'
});
// child
new IframeClient({
type: 'child',
targetWindow: window.parent,
namespace: 'xxx'
});targetOrigin: 'https://your-domain.com'client.destroy();- origin 校验
- source 校验
- namespace 隔离
- 内部消息标识过滤
const client = new IframeClient({ ... });
client.sendMessage('INIT'); // ❌👉 直接无法通信
A: 在握手完成后触发(READY / ACK 完成)。
支持所有 结构化克隆数据:
- ✅ Object / Array
- ✅ Map / Set
- ✅ ArrayBuffer
- ❌ Function / DOM
可以,用原生:
window.postMessage(...)
window.addEventListener('message', ...)但你需要自己处理:
- 握手
- 安全校验
- 消息管理
MIT
❤️ Made with ❤️