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