@cartridge/penpal

中文文档
6.2.4发布于 2025/01/28MITTypeScriptESM + CJS零依赖近 30 天下载 4.2万

一个基于承诺的图书馆,通过Message后与iframes通信.

中文使用文档
文档目录17 节
  1. 从第五版升级? 见 第6版发布注释 详细情况.
  2. 安装
  3. 使用 npm
  4. 使用 CDN 软件
  5. 使用量
  6. 父窗口
  7. 儿童框架
  8. API 密码
  9. connectToChild(options: Object) => Object
  10. connectToParent([options: Object]) => Object
  11. 重新连接
  12. 错误
  13. 类型脚本
  14. 反应
  15. 支持的浏览器
  16. 灵感
  17. 许可证

npm version

从第五版升级? 见 第6版发布注释 详细情况.

见文件5.x
见4.x的文件
见3.x的文件

彭帕尔

Penpal是一个基于承诺的图书馆,通过后Message安全地与iframes通信. 母窗口可以调用被 Iframes 曝光的方法,通过参数,并收到返回值. 同样地,iframes可以调用被母窗口曝光的方法,传递参数,并获得回取值. 轻松点.

这个库没有依赖关系.

安装

使用 npm

最好能从npm开始用Penpal 和像捆绑机一样的 网络软件包, (中文(简体) ), 滚动,或 括号。如果使用 npm 来管理客户端软件包,则可以安装 Penpal ,其中:

npm install penpal

使用 CDN 软件

如果您不想使用 npm 来管理客户端软件包, Penpal 也在 a 中提供 UMD 分布 dist 在 CDN 上托管的文件夹 :

<script src="https://unpkg.com/penpal@^6/dist/penpal.min.js"></script>

Penpal 将安装在 window.Penpal。 。 。 . window.Penpal 将包含下列属性:

Penpal.connectToChild
Penpal.connectToParent
Penpal.ErrorCode.ConnectionDestroyed
Penpal.ErrorCode.ConnectionTimeout
Penpal.ErrorCode.NoIframeSrc

使用方法与使用捆绑器类似,下面对此有记载,但您不会导入每个模块,而是会在 Penpal 改为全球.

使用量

父窗口

import { connectToChild } from 'penpal';

const iframe = document.createElement('iframe');
iframe.src = 'http://example.com/iframe.html';

// This conditional is not Penpal-specific. It's merely
// an example of how you can add an iframe to the document.
if (
  document.readyState === 'complete' ||
  document.readyState === 'interactive'
) {
  document.body.appendChild(iframe);
} else {
  document.addEventListener('DOMContentLoaded', () => {
    document.body.appendChild(iframe);
  });
}

// This is where the magic begins.
const connection = connectToChild({
  // The iframe to which a connection should be made.
  iframe,
  // Methods the parent is exposing to the child.
  methods: {
    add(num1, num2) {
      return num1 + num2;
    },
  },
});

connection.promise.then((child) => {
  child.multiply(2, 6).then((total) => console.log(total));
  child.divide(12, 4).then((total) => console.log(total));
});

儿童框架

import { connectToParent } from 'penpal';

const connection = connectToParent({
  // Methods child is exposing to parent.
  methods: {
    multiply(num1, num2) {
      return num1 * num2;
    },
    divide(num1, num2) {
      // Return a promise if the value being
      // returned requires asynchronous processing.
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(num1 / num2);
        }, 1000);
      });
    },
  },
});

connection.promise.then((parent) => {
  parent.add(3, 1).then((total) => console.log(total));
});

API 密码

connectToChild(options: Object) => Object

Penpal 要正确操作, 你必须保证 connectToChild 在iframe呼叫前叫着 connectToParent。 。 。 . 如以上例子所示,设置 src 或者说 srcdoc iframe 属性,并在调用 connectToChild 只要它们都在同一处 Java 脚本事件循环。或者,您总是可以在文档中附加框架 之后 电话 connectToChild 改为 在此之前。 。 。 .

选项

options.iframe: HTMLIFrameElement (必须)

Penpal 应当连接的 Iframe 元素 。 除非你提供 childOrigin 选项,您需要设置 src 或者说 srcdoc iframe 呼叫前的财产 connectToChild 这样Penpal就可以自动获得孩子的血统. 除了普通的URL外, 数据 URIs 财务报告和审定财务报表 文件 URIs 也得到支持.

options.methods: Object (可选)

含有儿童iframe调用方法的物体。 对象的键是方法名,值是函数. 带有函数值的嵌入对象被递归包含. 如果一个函数需要同步处理来确定其返回值,则使函数立即返回一个承诺,并在确定值后解决承诺.

options.childOrigin: string (可选)

在绝大多数情况下,Penpal可以自动根据儿童出生情况确定儿童出身 src 或者说 srcdoc 设置在 iframe 上的属性。 通信将自动限于这一来源.

在一些罕见的情况下,特别是在使用 file:// 在各种设备上的协议,浏览器在如何报告和处理来源上不一致. 如果您收到一个错误, 表示父母收到来自意外来源的握手, 您可能需要使用此选项手动传递孩子来源 .

其他情况 特殊情景,您可能希望父母能够与任何儿童血统进行沟通。 在这种情况下,你可以设置 childOrigin 改为 *。 。 。 . 这是令人沮丧的. 为了说明这种风险,如果一个邪恶的攻击者设法在孩子的页面内创建一个链接,让另一个用户可以点击(例如,如果你未能在信件板注释中不适当地逃脱 HTML),并且这个链接会引导不可疑的用户的iframe到邪恶的URL,那么邪恶的URL的页面就可以开始与你的母窗口通信.

无论你如何配置 childOrigin,通信将始终被限制在 iframe 中您正在连接.

options.timeout: number (可选)

时间之多,以毫秒计,彭帕勒应等孩子回应后再拒绝连接承诺. 默认没有超时.

options.debug: boolean (可选)

启用或禁用调试日志 。 除错日志默认已禁用 .

返回值

返回值为 connectToChild 是一个 connection 具有下列属性的对象:

connection.promise: Promise

承诺一旦达成就会实现 承诺将用一个包含儿童暴露的方法的物体来解决。 注意,这些并不是关于孩子所接触的方法的实际记忆参考,而是彭帕勒用相同的名字和签名创建的代理方法. 当其中一种方法被调用时,彭帕勒会立即返回一个承诺,然后去工作,向孩子发送一个信息,用你通过的论点调用孩子内部的实际方法,然后将返回值寄回给父母. 你得到的允诺将按回报值解决.

connection.destroy: Function

一种在调用时会断开任何消息通道的方法. 在连接建立之前,您也可以拨打这个电话.

connectToParent([options: Object]) => Object

选项

options.parentOrigin: string | RegExp (可选) 但建议很高!(中文(简体) )

您的 iframe 将与之通信的父窗口的来源 。 如果不提供,通信将不局限于任何特定的父来源,从而导致任何网页能够将您的网页装入iframe并与它通信.

options.methods: Object (可选)

包含用于母窗口调用的方法的对象 。 对象的键是方法名,值是函数. 带有函数值的嵌入对象被递归包含. 如果一个函数需要同步处理来确定其返回值,则使函数立即返回一个承诺,并在确定值后解决承诺.

options.timeout: number (可选)

时间量,以毫秒计,Penpal应等父母回复后再拒绝连接承诺. 默认没有超时.

options.debug: boolean (可选)

启用或禁用调试日志 。 除错日志默认已禁用 .

返回值

返回值为 connectToParent 是一个 connection 具有下列属性的对象:

connection.promise: Promise

承诺一旦达成就会实现 承诺将通过包含父母曝光的方法的对象解决。 注意,这些并非对母体所暴露的方法的实际内存参考,而是彭帕勒用同名和签名创建的代理方法. 当其中一种方法被调用时,彭帕尔会立即返回一个承诺,然后去工作,向父母发送一个信息,用您通过的论点调用父母内部的实际方法,然后将返回值发送给孩子. 你得到的允诺将按回报值解决.

connection.destroy: Function

一种在调用时会断开任何消息通道的方法. 在连接建立之前,您也可以拨打这个电话.

重新连接

如果孩子iframe试图与父母重新连接,父母会接受新的连接. 例如,如果用户将孩子的iframe刷新或浏览到另一个同样使用Penpal的页面,就可能出现这种情况. 在这种情况下 child 对象,在初始连接建立时,父母会根据孩子iframe提供的新方法更新.

注:目前没有API通知消费者重新连接。 如果这对您很重要,请提供反馈 这个问题 以及你希望看到 API 设计.

错误

Penpal会在某些情况下抛出(或拒绝承诺)错误。 每个错误都会有一个 code 属性,可用于程序决策(例如,如果错误是由于连接时断时而发生)以及 message 描述问题。 下列代码可能会出错 :

ConnectionDestroyed

当尝试调用方法时, 此错误会被抛出 child 或者说 parent 对象和连接先前已被销毁.

ConnectionTimeout

承诺在 connection.promise 会在 timeout 期限已过,尚未建立联系.

NoIframeSrc

当 iframe 传递到 connectToChild 没有 src 或者说 srcdoc 设置.

为了方便,这些错误代码可以导入如下:

import { ErrorCode } from 'penpal';
// ErrorCode.ConnectionDestroyed
// ErrorCode.ConnectionTimeout
// ErrorCode.NoIframeSrc

类型脚本

打电话时 connectToChild 或者说 connectToParent,您可以通过一个通用类型的参数。 这将用于键入 child 或者说 parent 对象 connection.promise 解决了。 这一点在代码中得到更好的解释:

import { connectToChild } from 'penpal';

// This interace could be imported from a code library
// that both the parent and child share.
interface ChildApi {
  multiply(...args: number[]): number;
}

// Supply the interface as a generic argument.
const connection = connectToChild<ChildApi>({
  iframe: new HTMLIFrameElement(),
});

// The resulting child object will contain properly
// typed methods.
const child = await connection.promise;
// The result variable is typed as a number.
const result = await child.multiply(1, 3);

下列类型也会导出为您使用的命名常数 :

  • Connection
  • Methods
  • AsyncMethodReturns
  • CallSender
  • PenpalError

反应

如果你在React应用软件中使用了Penpal 请检查一下 @weblivion/react-penpal。 。 。 .

支持的浏览器

Penpal被设计成功运行在Chrome,Firefox,Safari,和Edge等最新版本上. 如果您需要支持Internet Explorer 11,请随意使用Penpal的3.x版本. 见 3.x 读取 用于文档.

据报道,Penpal还在iOS和Android装置的Ionic项目内工作.

灵感

这个图书馆的灵感来自:

许可证

麻省理工学院

版本与发布记录

@cartridge/penpal 共发布 3 个版本,首次发布于 2022/10/01;过去 12 个月发布了 0 个版本。

版本发布日期距今
6.2.4latest2025/01/281.8 年前
6.2.32022/10/014 年前
6.2.22022/10/014 年前

关于 @cartridge/penpal 的常见问题

@cartridge/penpal 是什么?

一个基于承诺的图书馆,通过Message后与iframes通信.

如何安装 @cartridge/penpal?

在项目目录运行 npm install @cartridge/penpal,或使用 pnpm add / yarn add / bun add。

@cartridge/penpal 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cartridge/penpal 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cartridge/penpal 可以商用吗?

@cartridge/penpal 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cartridge/penpal 的下载量有多少?

根据 npm 官方下载统计,@cartridge/penpal 在 2026/10/09 – 2026/11/07 这 30 天内被下载 41,921 次,日均约 1,397 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cartridge/penpal 还在维护吗?

最新版本 6.2.4 发布于 2025/01/28(1.8 年前);至今共发布 3 个版本,其中过去 12 个月发布了 0 个;首次发布于 2022/10/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。