核心是“本地暂存+状态标记+冲突可控上行同步”:用indexeddb(或dexie.js)存草稿,含issynced等字段;三态管理(draft/syncing/synced);客户端生成clientopid与contenthash实现幂等;online时异步限速同步,多标签页一致。

用前端数据库实现离线草稿箱与同步,核心是“本地暂存 + 状态标记 + 冲突可控的上行同步”。关键不在存数据,而在管状态、识差异、控重试。
选对数据库:优先 IndexedDB,轻量场景可选 localStorage
IndexedDB 支持事务、索引、大量结构化数据,适合草稿箱这类需频繁增删查、带元信息(如 isSynced、updatedAt、conflictId)的场景。localStorage 仅适合极简表单草稿(如单字段文本+时间戳),且无事务保障,多标签页易覆盖。
- 用 Dexie.js 封装 IndexedDB,写法接近 Promise,自动处理版本升级和索引创建
- 为草稿对象设计固定 schema:id(自增或 UUID)、content(JSON 字符串或结构化对象)、isSynced(boolean)、syncError(string|null)、updatedAt(Date.now())
- 建复合索引如 "isSynced+updatedAt",方便快速查未同步项并按时间排序
草稿生命周期管理:三态驱动操作逻辑
每条草稿明确处于 draft(未提交)、syncing(正在同步)、synced(已确认服务端接收)三种状态之一,避免重复提交或丢失更新。
- 用户编辑时只写入 draft 状态草稿;点击“保存草稿”即存入 IndexedDB,不发请求
- 点击“发布”或网络恢复时,批量取出 isSynced: false 的草稿,按 updatedAt 升序逐条发起 POST 请求
- 成功后更新该条 isSynced = true;失败则设 syncError = 错误信息,并保留原草稿供用户重试或编辑
同步冲突处理:以客户端时间戳为主,服务端做幂等校验
不依赖服务端生成 ID 或版本号(离线时不可用),改用客户端生成唯一操作 ID(如 UUID + 时间戳)+ 内容哈希,服务端据此判断是否已处理过。
- 每次草稿提交携带 clientOpId(首次生成后固定)和 contentHash(如 SHA-256(content))
- 服务端收到后查 clientOpId 是否存在;若存在,比对 contentHash —— 相同则返回 200(幂等),不同则返回 409 并附服务端当前内容,触发前端合并提示
- 前端不自动合并,而是将服务端内容展示为“远程版本”,让用户选择保留本地、覆盖本地,或手动合并
网络恢复自动同步:监听 online 事件 + 后台队列重试
离线期间所有同步请求缓存在 IndexedDB,上线后不阻塞 UI,用 Web Worker 或 requestIdleCallback 异步执行。
- 监听 window.addEventListener('online', handleSyncQueue),但首次加载也需主动检查 navigator.onLine 并触发一次同步
- 同步队列加限速:每次最多并发 3 条请求,失败后指数退避(1s → 3s → 9s),超 5 次失败标记为“需人工干预”
- 用户切换页面前,用 beforeunload 提示“有未同步草稿”,避免意外丢失
不复杂但容易忽略的是状态一致性——草稿是否同步,必须只由 IndexedDB 中的字段决定,而非内存变量或临时 flag。每次读写都走数据库,才能保证多标签页、刷新、崩溃后行为可靠。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










