npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@giszhc/iframe-client

v0.0.5

Published

一个 简单、轻量、专注通信 的 JavaScript / TypeScript 库,用于 iframe 跨域消息传递。

Readme

Iframe Client

一个 简单、轻量、专注通信 的 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);
});

子页面(iframe 内)

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 });
});

API

配置

interface IframeClientConfig {
  type: 'parent' | 'child';
  iframe?: HTMLIFrameElement;
  targetWindow?: Window;
  targetOrigin?: string;
  namespace: string;
  onConnect?: () => void;
  onError?: (error: Error) => void;
}

sendMessage

client.sendMessage('EVENT', { data: 1 });

on

client.on('EVENT', (data, event) => {
  console.log(data);
});

off

client.off('EVENT', handler);

destroy

client.destroy();

isConnected

client.isConnected();

🔁 通信流程示例

【握手阶段】
child  → READY
parent → ACK

【业务通信】
parent → INIT
child  → RESPONSE

⚠️ 注意事项

1️⃣ 必须使用 namespace

// ❌ 错误
namespace: 'a'
namespace: 'b'

// ✅ 正确
namespace: 'my-app:demo:v1'

2️⃣ 不要提前发送消息

// ❌ 错误
client.sendMessage('INIT');

// ✅ 正确
onConnect: () => {
  client.sendMessage('INIT');
}

3️⃣ 必须传正确参数

// parent
new IframeClient({
  type: 'parent',
  iframe,
  namespace: 'xxx'
});

// child
new IframeClient({
  type: 'child',
  targetWindow: window.parent,
  namespace: 'xxx'
});

4️⃣ 生产环境不要用 '*'

targetOrigin: 'https://your-domain.com'

5️⃣ 记得销毁

client.destroy();

🔐 安全机制

  • origin 校验
  • source 校验
  • namespace 隔离
  • 内部消息标识过滤

❌ 常见错误

提前发送消息(会丢)

const client = new IframeClient({ ... });

client.sendMessage('INIT'); // ❌

namespace 不一致

👉 直接无法通信


FAQ

Q: onConnect 什么时候触发?

A: 在握手完成后触发(READY / ACK 完成)。


Q: payload 支持什么类型?

支持所有 结构化克隆数据

  • ✅ Object / Array
  • ✅ Map / Set
  • ✅ ArrayBuffer
  • ❌ Function / DOM

Q: 可以不用这个库吗?

可以,用原生:

window.postMessage(...)
window.addEventListener('message', ...)

但你需要自己处理:

  • 握手
  • 安全校验
  • 消息管理

📄 License

MIT


❤️ Made with ❤️