← 单实例示例 | 核心 API →
多实例演示使用独立 Subframe:父页面负责 Tab 和工具栏,每个 Tab 的 OnlyOffice Embed SDK 运行时都放在一个独立子域名页面中。
onlyoffice.localhost
├── rat.onlyoffice.localhost/subframe (🐀 鼠)
├── ox.onlyoffice.localhost/subframe (🐂 牛)
├── tiger.onlyoffice.localhost/subframe (🐅 虎)
├── rabbit.onlyoffice.localhost/subframe (🐇 兔)
├── dragon.onlyoffice.localhost/subframe (🐉 龙)
├── snake.onlyoffice.localhost/subframe (🐍 蛇)
├── horse.onlyoffice.localhost/subframe (🐎 马)
├── goat.onlyoffice.localhost/subframe (🐐 羊)
├── monkey.onlyoffice.localhost/subframe (🐒 猴)
├── rooster.onlyoffice.localhost/subframe (🐓 鸡)
├── dog.onlyoffice.localhost/subframe (🐕 狗)
└── pig.onlyoffice.localhost/subframe (🐖 猪)
生产环境将上述主机名替换为 rat.onlyoffice.agent-bridges.com 等固定 12 个槽位。每个子框架的响应都带有 Origin-Agent-Cluster: ?1。因此 SDK 的全局对象、事件总线、socket mock 和文档状态不会在多实例之间共享;父页只通过带 source、实例 ID 和精确目标 origin 校验的 postMessage RPC 控制子框架。
在线演示:站点路由 /docs/demos/multi
父页面源码:src/features/demo/tabs-multi-page.tsx
子框架页面:src/features/demo/onlyoffice-subframe-page.tsx
消息协议:src/features/demo/subframe-protocol.ts
下方为可交互的多实例 Tab 编辑器。
| 要点 | 说明 |
|---|
| 固定槽位 | 按鼠、牛、虎、兔、龙、蛇、马、羊、猴、鸡、狗、猪顺序分配 12 个固定槽位,关闭后可复用 |
| 独立 origin | 第一个 Tab 使用 rat.onlyoffice.localhost,后续 Tab 依次使用 ox.onlyoffice.localhost、tiger.onlyoffice.localhost |
| Tab 标识 | 每个 Tab 显示对应的生肖 emoji,便于在多个编辑器之间快速区分 |
| 独立运行时 | 每个 /subframe 页面拥有自己的 OnlyOfficeManager、SDK 和事件总线 |
| 懒加载 | Tab 首次激活时,父页通过 RPC 发送 open 请求 |
| 状态保留 | 非激活 Tab 只隐藏外层 iframe,不卸载子框架 |
| 跨窗口控制 | 上传、主题、只读、导出、批注、修订和 Connector 都通过 RPC 转发 |
| 关闭 Tab | 父页发送 destroy,再移除对应 iframe |
| 资源切换 | 更新 iframe 的资源参数并重新加载各子框架 |
| 响应头 | TanStack Start 的 Cloudflare Worker 全局响应头设置 Origin-Agent-Cluster: ?1 |
type TabItem = {
id: string;
label: string;
containerId: string;
subframeHost: string;
chineseZodiac: { id: string; name: string; emoji: string };
fileName: string;
readOnly: boolean;
docKind: "word" | "excel" | "ppt";
};
const url = new URL("/subframe", getSubframeOrigin(tab.subframeHost));
url.searchParams.set("instance", tab.id);
url.searchParams.set("resourceMode", resourceState.mode);
getSubframeOrigin("rat") 在本地开发时返回 http://rat.onlyoffice.localhost:<port>;生产环境返回 https://rat.onlyoffice.agent-bridges.com。12 个固定主机名都指向同一个 Cloudflare Worker,但每个主机名仍然是独立 origin。
iframe load → subframe:ready
parent → request/open
subframe → event/loading-change + event/document-ready
subframe → response/open
parent → request/set-theme | request/set-read-only | request/editor
子框架不会把 SDK 原始对象传回父页:批注和修订会先转换为可结构化克隆的数据,Connector 命令则只传递函数源码字符串和调用结果。