窗口消息
使用 window.postMessage() 在宿主页面与 iC Candle iframe 之间交换状态。
所有入站消息都应校验 event.origin === "https://embed-iccandle-app.iccandle.ai"。父页面向嵌入端发送消息时,也应把同一 origin 作为 targetOrigin。
消息传输
嵌入端消息可能以以下任一形式到达:
- 普通 JavaScript 对象
- 需要
JSON.parse()的 JSON 字符串
在分发前先统一解析 event.data:
const EMBED_ORIGIN = "https://embed-iccandle-app.iccandle.ai";
window.addEventListener("message", (event) => {
if (event.origin !== EMBED_ORIGIN) return;
let message;
try {
message =
typeof event.data === "string" ? JSON.parse(event.data) : event.data;
} catch {
return;
}
handleEmbedMessage(message);
});
父页面 -> 嵌入端
parent-origin
告诉 iframe,Stripe Checkout 返回 URL 应该使用哪个父页面 origin。
type ParentOriginMessage = {
type: "parent-origin";
origin: string;
};
示例:
iframe.contentWindow.postMessage(
{ type: "parent-origin", origin: window.location.origin },
EMBED_ORIGIN,
);
payment-success
当 Stripe 重定向回你的宿主页面后,通知 iframe 刷新订阅 / 积分状态。
type PaymentSuccessMessage = {
type: "payment-success";
};
示例:
iframe.contentWindow.postMessage({ type: "payment-success" }, EMBED_ORIGIN);
嵌入端 -> 父页面
iframe 消息通常使用 name + data 包裹格式:
type EmbedMessageEnvelope = {
name?: string;
data?: unknown;
pattern?: unknown;
};
name 消息
name | 载荷结构 | 触发时机 | 宿主动作 |
|---|---|---|---|
auth.signIn | { name: "auth.signIn", data: { idToken: string } } | iframe 内登录完成 | 若宿主要调用 iC Candle API,则将 data.idToken 存为 iccandle_token |
selector.loading | { name: "selector.loading", data: { isLoading: boolean } } | 扫描或 AI 准备开始 / 结束 | 显示或隐藏加载 UI |
chart.play | { name: "chart.play", data: { isReplay: true, predictCandles?: Candle[] | null, playEndTimestamp: number | null, selectedCandles: Candle[] | null } } | 用户从图表或新闻流程启动回放 | 注入回放 K 线或生成 K 线 |
chart.stop | { name: "chart.stop", data: { isReplay: false, predictCandles?: Candle[] | null, playEndTimestamp: null, selectedCandles: null } } 或 { name: "chart.stop", data: null } | 回放被清除或关闭 | 移除回放 K 线与仅在回放时存在的叠加 |
selector.closeResult | { name: "selector.closeResult", data: null } | 当前扫描结果面板关闭 | 清除结果专属叠加 |
nav.click | { name: "nav.click", data: { href: string } } | 用户点击嵌入端头部导航 | 可选,响应标签或路由切换 |
news.eventClicked | { name: "news.eventClicked", data: { event: NewsEvent, similarDetails: object | null } } | 用户选中一个经济事件 | 将图表居中到事件位置并绘制相关标记 |
news.selectedEventPayloads | { name: "news.selectedEventPayloads", data: NewsEvent[] } | 用户选择扫描器中的新闻事件 | 持久化所选事件,用于时间轴标记或叠加 |
news.back | { name: "news.back", data: null } | 用户离开新闻详情 | 清除事件专属图表装饰 |
news.backToSimilarEvents | { name: "news.backToSimilarEvents", data: null } | 用户在相似事件流程内返回 | 与 news.back 相同的清理逻辑 |
news.iframeReady | { name: "news.iframeReady", data: null } | 相似事件 iframe 完成初始加载 | 可选生命周期钩子 |
news.analyzeImpact | { name: "news.analyzeImpact", data: null } | 用户请求影响分析 | 可选分析扩展钩子 |
playEndTimestamp 使用 unix 秒。
形态选择消息
形态流程也使用 name + data 包裹格式:
| 结构 | 触发时机 | 宿主动作 |
|---|---|---|
{ name: "pattern.classicPatternSelected", data: { pattern: object } } | 用户选择一个经典 / 通用形态匹配 | 高亮对比形态区间 |
{ name: "pattern.clearClassicPatternSelected", data: null } | 用户清除经典 / 通用形态选择 | 移除高亮 |
{ name: "pattern.custom_pattern_selected", data: { pattern: object } } | 用户选择一个追踪形态 | 高亮追踪形态区间 |
{ name: "pattern.clear_custom_pattern_selected", data: null } | 用户清除追踪形态选择 | 移除追踪形态高亮 |
宿主通常只需要每个形态的起止时间戳,或图表库所需的等价区间字段。
推荐路由方式
处理 iframe 输出时,优先按 message.name 路由。
下一步
参见 数据类型 了解 Candle、NewsEvent、回放载荷与认证消息体等共享结构。