离线数据可用的核心是“先查缓存、再发请求、成功后更新缓存”,结合 localStorage/sessionStorage(简单键值)、Cache API+Service Worker(PWA离线优先)、IndexedDB(大量结构化数据)及网络状态协同设计。

JavaScript 中用 Ajax 配合本地缓存实现离线数据可用,核心是“先查缓存、再发请求、成功后更新缓存”,同时做好网络异常时的降级处理。关键不在于堆砌技术,而在于控制读写时机和一致性。
用 localStorage 或 sessionStorage 做简单键值缓存
适合结构简单、更新不频繁的数据(如用户配置、静态字典、列表页快照)。注意:localStorage 无过期机制,需手动管理;sessionStorage 关闭标签页即失效,适合临时状态。
- 读取时优先从 localStorage 获取,有则直接渲染,避免白屏或 loading 卡顿
- 发送 Ajax 请求获取最新数据,无论成功与否,都应在回调中统一处理缓存逻辑
- 请求成功后,把新数据存入 localStorage,并触发视图更新;失败时保留旧缓存,提示“已加载离线内容”
- 可加时间戳字段(如
data._cachedAt = Date.now())辅助判断缓存是否过期,但不必强求实时刷新
用 Cache API + Service Worker 实现真正离线优先
这是 PWA 场景下的标准方案,能拦截网络请求、缓存响应体(含 HTML/CSS/JS/JSON),支持精细缓存策略(如 stale-while-revalidate)。
- 注册 Service Worker 后,在其
install阶段预缓存核心资源(如首页、离线页面) - 在
fetch事件中拦截 API 请求:优先匹配 cache,未命中再走网络;网络响应返回后,再写入 cache 更新 - 前端调用
fetch('/api/list')即可,无需改业务代码——缓存逻辑由 SW 在底层接管 - 注意:Cache API 只在 HTTPS 或 localhost 下可用;首次访问不会触发 install,需二次刷新才生效
结合 IndexedDB 处理大量结构化离线数据
当需要缓存分页列表、带关系的用户笔记、本地编辑暂存等场景,localStorage 容量和查询能力都不够,IndexedDB 是更合适的选择。
立即学习“Java免费学习笔记(深入)”;
- 用
open()创建数据库,定义 objectStore 存储 JSON 数据,支持索引、事务、游标遍历 - Ajax 成功后,将响应数据通过
add()或put()写入 DB;读取时用get()或getAll(),支持条件查询 - 可封装一个轻量 DAO 类,统一处理“读 IDB → 失败则 fetch → fetch 成功再写 IDB”的流程,对外暴露 Promise 接口
- 注意错误边界:IDB 操作异步且易出错(如版本冲突、存储满),务必包裹 try/catch 并 fallback 到内存缓存或空数据
网络状态与用户体验协同设计
离线能力不只是技术问题,更是体验问题。用户需要明确感知当前是在线、弱网还是离线,并知道操作是否已生效。
- 监听
navigator.onLine变化,动态切换 UI 状态(如顶部提示条:“离线模式,部分功能受限”) - 对写操作(如提交表单),即使离线也要先存入本地(IDB 或内存队列),待联网后自动同步,同步成功再清除本地记录
- 避免“假离线”:有些设备 WiFi 连接但无外网,
onLine仍为 true,建议配合定时 ping 接口(如/health)做双重判断 - 给用户控制权:提供“强制刷新”按钮,跳过缓存直连服务器;也提供“清空离线数据”入口,便于调试和释放空间


















