2022-02-21 06:32:56
构建支持离线同步的笔记类Web应用需围绕离线访问、本地存储、增量同步和状态提示四大核心模块展开,结合Service Worker、IndexedDB、后台同步API等技术实现。 以下是具体实现方案:
一、离线访问:Service Worker与缓存策略注册与激活Service Worker
在主线程中通过navigator.serviceWorker.register()注册,指定JS文件路径(如sw.js)。
在sw.js中监听install事件,预缓存关键静态资源(HTML、CSS、JS、图标等),使用caches.open()创建缓存空间并存储资源。
示例代码:self.addEventListener('install', (event) => { event.waitUntil( caches.open('note-app-v1').then((cache) => { return cache.addAll(['/', '/index.html', '/style.css', '/app.js']); }) );});
请求拦截与缓存策略
监听fetch事件,根据资源类型选择策略:
网络优先:先尝试从网络获取,失败后返回缓存(适合频繁更新的资源)。
缓存优先:直接返回缓存,仅当缓存不存在时请求网络(适合静态资源)。
示例代码(网络优先):self.addEventListener('fetch', (event) => { event.respondWith( fetch(event.request).catch(() => caches.match(event.request)) );});
结构化数据存储(IndexedDB)
存储笔记的标题、内容、时间戳、版本号等结构化数据,支持大量数据存储和复杂查询(如按时间排序)。
使用indexedDB.open()创建数据库,定义对象仓库(Object Store)存储笔记数据。
示例代码:const request = indexedDB.open('NoteDB', 1);request.onupgradeneeded = (event) => { const db = event.target.result; db.createObjectStore('notes', { keyPath: 'id', autoIncrement: true });};
轻量状态存储(localStorage)
保存当前编辑的草稿、用户偏好(如主题颜色)等轻量数据。
示例代码:localStorage.setItem('currentDraft', JSON.stringify({ title: '', content: '' }));
统一数据访问层
封装CRUD操作,屏蔽底层存储差异(如IndexedDB的异步操作与localStorage的同步操作)。
示例接口设计:class DataLayer { async saveNote(note) { /* 写入IndexedDB */ } getDraft() { /* 读取localStorage */ } // 其他方法...}
本地变更标记
为每条笔记记录lastModified时间戳或版本号,同步时仅上传修改过的数据。
示例数据结构:{ id: 1, title: '示例笔记', content: '...', lastModified: Date.now(), isSynced: false // 标记是否已同步}
后台同步(Background Sync)
使用sync事件延迟触发同步任务,即使应用关闭后网络恢复也能自动执行。
注册同步任务:navigator.serviceWorker.ready.then((sw) => { sw.sync.register('sync-notes').catch((err) => console.error('Sync failed:', err));});
冲突处理策略
最后写入胜出:比较时间戳,保留较新的版本。
用户手动合并:检测到冲突时提示用户选择保留本地或服务器版本。
服务端需支持PATCH接口,仅更新指定字段,减少传输开销。
实时监听网络变化
监听window.online和window.offline事件,更新应用状态。
示例代码:window.addEventListener('online', () => updateUI('已恢复网络'));window.addEventListener('offline', () => updateUI('当前离线'));
同步进度提示
在UI中显示“正在同步”“同步完成”等状态,增强用户信任感。
示例设计:
顶部状态栏:显示网络状态(在线/离线)。
同步按钮:同步时显示加载动画,完成后弹出提示。
用户离线编辑笔记
数据写入IndexedDB,标记isSynced: false。
草稿保存到localStorage。
网络恢复后自动同步
Service Worker触发sync事件,调用数据层获取未同步笔记。
通过PATCH接口上传变更,服务端返回结果后更新本地isSynced状态。
冲突处理
若服务端数据版本较新,根据策略合并或提示用户。
通过以上设计,可实现一个可靠的离线同步笔记应用,核心在于Service Worker的缓存管理、IndexedDB的数据存储、增量同步逻辑与用户状态反馈的紧密配合。