浏览器缓存不保存表单数据,真正保障离线提交的是localStorage/IndexedDB与Service Worker协同:前者暂存数据,后者在网络恢复后自动重发。

浏览器缓存本身不直接参与离线表单提交的数据保存,真正起保障作用的是本地存储机制(如 localStorage、IndexedDB)与 Service Worker 协同工作。浏览器的 HTTP 缓存(如强缓存、协商缓存)只管静态资源(HTML/CSS/JS),对用户填写的动态表单数据完全无效。要实现“断网时填完不丢、联网后自动发”,关键在于把数据主动存到本地数据库,并由 Service Worker 负责调度重发。
用 localStorage 快速暂存简单表单
适合字段少、结构扁平、无需事务或大量数据的场景(比如登录、搜索、反馈表单):
- 监听表单 input 或 change 事件,实时将字段名和值写入 localStorage,例如:
localStorage.setItem('form-username', e.target.value) - 页面加载时遍历表单元素,从 localStorage 读取对应 key 并还原 value
- 提交前生成唯一 ID(如
crypto.randomUUID()),连同数据一起存入,便于后续追踪和去重 - 注意:localStorage 是同步阻塞 API,大数据量或高频操作时建议改用 IndexedDB
用 IndexedDB 存储结构化待提交记录
这是生产环境推荐方案,支持事务、索引、大容量和二进制数据,能可靠管理“待发队列”:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 建一个名为
pendingSubmissions的 object store,每条记录包含:id、url、method、body(序列化后的 FormData 或 JSON)、timestamp、status('pending' / 'failed' / 'sent') - 拦截表单 submit 事件,阻止默认行为,用
new FormData(form)提取数据,再转为纯对象存入 IndexedDB - 为每条记录添加过期时间(如 72 小时),避免长期堆积;失败重试次数上限设为 3 次
Service Worker 负责网络恢复后的自动重发
它不直接“缓存表单”,而是作为后台调度器,把本地存好的数据变成真实请求:
立即学习“Java免费学习笔记(深入)”;
- 注册 sync 事件:
self.registration.sync.register('submit-form')(Chrome/Edge 支持,Safari 不支持) - 在 Service Worker 中监听
sync事件,打开 IndexedDB,查询 status 为 'pending' 的记录 - 对每条记录执行
fetch(url, { method, body, headers }),成功则更新 DB 中 status 为 'sent';失败则标记为 'failed' 并保留 - Safari 等不支持 sync 的浏览器,可用
postMessage由页面主动通知 Service Worker 触发重发
页面加载时同步状态并提示用户
刷新后用户需要知道“我刚填的还在不在?有没有发出去?”:
- 页面初始化时打开 IndexedDB,查出所有
status !== 'sent'的记录 - 根据状态显示不同 UI:如“已暂存,正在等待网络…”、“提交失败,请点击重试”
- 提供手动重试按钮,点击后向 Service Worker 发送
{ type: 'retry', id: 'xxx' }消息 - 配合服务端幂等设计(如用前端传来的 UUID 做 Redis 去重),避免重发导致重复提交

















