在集成 ONLYOFFICE 的过程中,开发者经常会遇到两类问题:多人协同编辑后,再次打开文档发现刚才修改的内容缺失;或者重新打开文档时提示"文档版本已更新"。
这类问题很多时候并不是 ONLYOFFICE 不稳定,也不是协同编辑本身有问题,而是对 document.key 的机制理解不准确。简单来说,document.key 不能理解为普通的文件 ID,它更接近于"当前文档内容版本的唯一标识"。
1. ONLYOFFICE 编辑的不是原始文件
在很多系统的直觉理解中,浏览器似乎是在直接编辑服务器上的 Word 文件。但 ONLYOFFICE 的真实编辑流程并不是这样。
text
原始 Word 文件
↓
DocumentServer 下载文件
↓
转换为内部中间格式 Editor.bin
↓
浏览器加载并渲染 Editor.bin
↓
多人协同编辑 Editor.bin
↓
生成新的 output.docx
也就是说,用户在浏览器里编辑的并不是原始 Word 文件,而是 ONLYOFFICE 内部转换后的协同编辑文件。只有在特定时机,ONLYOFFICE 才会重新生成新的 Word 文件,并通过 callback 通知业务系统下载保存。
2. document.key 的本质
document.key 的本质不是文件 ID,而是:
当前文档内容版本的唯一身份标识。
它决定了 ONLYOFFICE 是否认为多个用户正在编辑同一个版本的文档。
| 判断项 | document.key 的作用 |
|---|---|
| 是否进入同一协同会话 | 相同 key 进入同一协同编辑状态 |
| 是否复用缓存 | 相同 key 可能复用已有转换缓存 |
| 是否重新下载文件 | key 变化后通常会被视为新版本 |
| 是否出现版本冲突 | key 与文件内容不匹配时容易触发 |
| 历史版本是否连续 | key 与版本管理策略相关 |
因此,document.key 最重要的设计原则是:
text
内容不变,key 不变
内容变化,key 必须变化
3. 一个标准的编辑生命周期
假设系统中有一个初始文档版本 v0,对应的 key 为 key0。
3.1 第一次打开文档
业务系统返回 ONLYOFFICE 配置,其中包含:
javascript
document: {
key: "key0",
title: "example.docx",
url: "https://example.com/example.docx"
}
DocumentServer 会根据 url 下载原始文件,并将其转换为内部中间格式。转换后的缓存文件通常位于:
text
/var/lib/onlyoffice/documentserver/App_Data
3.2 多人进入协同编辑
如果多个终端使用同一个 key0 打开文档,则它们会进入同一个协同编辑会话。此时 callback 可能收到 status = 1,表示已有用户进入编辑状态。
此阶段用户修改的内容主要存在于 ONLYOFFICE 的协同编辑缓存中,原始 Word 文件并不一定已经更新。
3.3 生成新版本文件
当所有用户退出编辑,或者系统开启强制保存并触发保存后,ONLYOFFICE 会生成新的结果文件,例如:
text
key0_123456/
├── changes.zip
└── output.docx
随后 callback 会收到 status = 2 或 status = 6。此时 callback 中的 url 指向的文件,才是本轮编辑后的最新文件。
3.4 业务系统保存新文件
收到 status = 2 或 status = 6 后,业务系统必须完成以下操作:
text
下载 callback 中的 url
↓
保存或覆盖原始业务文件
↓
更新文档版本号:v0 → v1
↓
下一次打开使用新的 key:key0 → key1
如果缺少其中任何一步,都可能导致内容丢失或版本冲突。
4. 为什么会出现"内容丢失"
所谓"内容丢失",通常不是 ONLYOFFICE 把内容弄丢了,而是业务系统没有把 ONLYOFFICE 生成的新文件保存下来。
错误流程如下:
text
用户协同编辑
↓
ONLYOFFICE 生成 output.docx
↓
callback 通知业务系统
↓
业务系统没有下载并保存 output.docx
↓
下一次打开时仍然加载旧文件
↓
用户看到刚才编辑的内容不见了
正确做法是:只要收到有效的保存回调,就必须下载 callback 中的文件地址,并将该文件保存为业务系统中的最新文件版本。
5. 为什么会提示"文档版本已更新"
"文档版本已更新"的本质,是 ONLYOFFICE 认为当前 key 对应的内容状态,与实际文件内容不一致。
常见原因如下。
| 场景 | 问题说明 | 结果 |
|---|---|---|
| 文件变了,key 没变 | 业务文件已经更新,但仍使用旧 key 打开 | 可能提示版本已更新 |
| key 变了,文件没变 | 文件内容没变化,但每次打开都生成新 key | 缓存失效,协同断裂 |
| 多人使用不同 key | 同一文件不同用户拿到不同 key | 无法进入同一协同会话 |
| callback 保存延迟 | 新文件尚未落库,下一次打开已使用新 key | 文件与 key 不匹配 |
| 多实例缓存不同步 | 应用层或存储层看到的文件版本不一致 | 偶发版本冲突 |
因此,document.key 必须和业务系统中的文件版本保持严格对应关系。
6. 企业系统推荐设计
在企业系统中,不建议直接使用文件 ID 作为 document.key。推荐使用"文档 ID + 版本号"的方式。
例如:
text
doc_1001_v1
doc_1001_v2
tenantA_doc_1001_v2
推荐维护如下字段:
| 字段 | 说明 |
|---|---|
| document_id | 业务文档 ID |
| version | 文档内容版本号 |
| file_path | 当前版本文件地址 |
| last_modified_time | 当前版本更新时间 |
| edit_status | 是否处于编辑中,可选 |
| latest_key | 当前版本对应的 key,可选 |
打开文档时,根据数据库中的当前版本生成 key:
javascript
key = documentId + "_v" + version;
例如当前版本是 27,则:
text
1001_v27
当 callback 保存成功后,版本号更新为 28,下一次打开应使用:
text
1001_v28
7. 推荐的 callback 处理逻辑
callback 是 ONLYOFFICE 集成中最关键的环节。建议按照以下逻辑处理。
text
收到 callback
↓
判断 status
↓
如果 status = 2 或 status = 6
↓
下载 callback.url 对应的新文件
↓
保存为业务系统最新文件
↓
更新数据库版本号
↓
返回 {"error": 0}
需要特别注意:文件下载和版本号更新应该尽量作为一个完整事务处理。不能出现"key 已更新,但文件还没保存成功"的中间状态,否则下一次打开就可能出现版本冲突。
8. 常见错误设计
错误一:永远使用 documentId 作为 key
javascript
key = documentId;
这种方式在第一次打开时可能没有问题,但当文件内容更新后,key 仍然不变,ONLYOFFICE 可能继续使用旧缓存,最终导致旧内容、版本冲突或协同异常。
错误二:每次打开都生成随机 key
javascript
key = UUID.randomUUID();
这种方式看似可以避免缓存问题,但会破坏协同编辑。因为每个用户、每次打开都被认为是一个新文档版本,结果是无法进入同一个协同编辑会话。
错误三:callback 中不保存新文件
这是导致"协同编辑后内容丢失"的主要原因。ONLYOFFICE 生成的 output.docx 不会自动覆盖业务系统中的文件,必须由业务系统在 callback 中下载并保存。
错误四:文件保存失败但版本号已更新
如果业务系统先更新版本号,再下载或保存文件,一旦保存失败,就会出现 key 对应新版本,但文件仍是旧内容的情况,进而引发"文档版本已更新"。
9. 推荐集成原则
可以将 ONLYOFFICE 的集成原则总结为以下几条:
| 原则 | 说明 |
|---|---|
| key 表示内容版本 | 不要把 key 简单等同于文件 ID |
| 内容变化才换 key | 文件没变化时不要随意换 key |
| callback 必须保存文件 | status = 2 或 6 时下载并保存新文件 |
| 保存成功后再更新版本 | 避免 key 与文件内容不一致 |
| 同一版本使用同一 key | 保证多人进入同一协同会话 |
| 新版本使用新 key | 避免复用旧缓存 |
| 多实例要保证一致性 | 文件、数据库、缓存中的版本要一致 |
10. 最终结论
ONLYOFFICE 的 document.key 是企业级集成中非常核心的字段。它不是简单的文件 ID,而是文档内容版本的唯一标识。
正确的设计应该是:
text
document.key = documentId + version
并且在 callback 中完成:
text
下载 output.docx
↓
保存为最新业务文件
↓
更新版本号
↓
下一次打开使用新的 key
只要业务系统能够保证"文件内容"和"document.key"始终一一对应,就可以有效避免多人协同后内容丢失、再次打开提示版本已更新、协同会话错乱等问题。
相关资源
- OnlyOffice最新版本9.x镜像:onlyoffice.moqisoft.com/docs/instal...
- 版本介绍:onlyoffice.moqisoft.com/docs/produc...
- OnlyOffice 中国版技术交流:qm.qq.com/q/YzEIuNe1y...