iframe-bridge-sdk
Version:
Universal iframe communication SDK - unified package for host and guest applications
144 lines • 4.32 kB
JavaScript
import { BaseMessenger, SDKState } from './shared';
/**
* Guest SDK - 在iframe中运行,与宿主应用通信
*/
export class GuestSDK extends BaseMessenger {
// ==================== 构造函数 ====================
constructor(config = {}) {
super();
/** 是否已初始化 */
this.initialized = false;
this.isInIframe = this.detectIframe();
this.targetOrigin = config.targetOrigin || '*';
// 如果不在iframe中,设置为就绪状态但不进行通信
if (!this.isInIframe) {
this.setState(SDKState.READY);
console.info('GuestSDK: Not running in iframe, communication disabled');
}
}
// ==================== 公共方法 ====================
/**
* 初始化Guest SDK
* @param config 配置选项
*/
init(config = {}) {
console.info('GuestSDK: init', config);
if (this.initialized) {
console.warn('GuestSDK already initialized');
return;
}
this.initialized = true;
// 更新配置
if (config.targetOrigin) {
this.targetOrigin = config.targetOrigin;
}
if (!this.isInIframe) {
console.info('GuestSDK: Not in iframe, skipping initialization');
return;
}
this.setState(SDKState.INITIALIZING);
this.setupMessageListener();
// 发送ready事件(除非配置禁用)
if (config.autoReady !== false) {
this.sendReady();
}
this.setState(SDKState.READY);
console.info('GuestSDK: Initialized successfully');
}
/**
* 手动发送ready事件
*/
sendReady() {
if (!this.isInIframe) {
console.warn('Cannot send ready event: not in iframe');
return;
}
this.emit('ready');
}
/**
* 检查是否在iframe中运行
*/
isIframe() {
return this.isInIframe;
}
/**
* 获取目标窗口来源
*/
getTargetOrigin() {
return this.targetOrigin;
}
/**
* 设置目标窗口来源
* @param origin 目标来源
*/
setTargetOrigin(origin) {
this.targetOrigin = origin;
}
// ==================== 受保护的方法 ====================
/**
* 实现抽象方法:发送消息到宿主窗口
* @param message 要发送的消息
*/
sendMessage(message) {
if (!this.isInIframe) {
console.warn('Cannot send message: not in iframe');
return;
}
if (this.getState() === SDKState.DESTROYED) {
console.warn('Cannot send message: SDK is destroyed');
return;
}
try {
window.parent.postMessage(message, this.targetOrigin);
}
catch (error) {
console.error('Failed to send message to parent:', error);
}
}
// ==================== 私有方法 ====================
/**
* 检测是否在iframe中运行
*/
detectIframe() {
try {
return window !== window.parent;
}
catch (error) {
// 在某些情况下访问window.parent可能抛出异常
return true;
}
}
/**
* 设置消息监听器
*/
setupMessageListener() {
const messageHandler = (event) => {
// 安全检查:验证消息来源
if (!this.isValidOrigin(event.origin)) {
return;
}
// 处理接收到的消息
this.handleIncomingMessage(event.data);
};
window.addEventListener('message', messageHandler);
// 在销毁时清理监听器
const originalDestroy = this.destroy.bind(this);
this.destroy = () => {
window.removeEventListener('message', messageHandler);
originalDestroy();
};
}
/**
* 验证消息来源是否有效
* @param origin 消息来源
*/
isValidOrigin(origin) {
// 如果targetOrigin是'*',则接受所有来源
if (this.targetOrigin === '*') {
return true;
}
// 检查是否匹配指定的来源
return origin === this.targetOrigin;
}
}
//# sourceMappingURL=guest.js.map