从第五版升级? 见 第6版发布注释 详细情况.
彭帕尔
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);
下列类型也会导出为您使用的命名常数 :
ConnectionMethodsAsyncMethodReturnsCallSenderPenpalError
反应
如果你在React应用软件中使用了Penpal 请检查一下 @weblivion/react-penpal。 。 。 .
支持的浏览器
Penpal被设计成功运行在Chrome,Firefox,Safari,和Edge等最新版本上. 如果您需要支持Internet Explorer 11,请随意使用Penpal的3.x版本. 见 3.x 读取 用于文档.
据报道,Penpal还在iOS和Android装置的Ionic项目内工作.
灵感
这个图书馆的灵感来自:
许可证
麻省理工学院