页面卸载时无法可靠发送异步请求,应采用“提前存+最后兜底”策略:beforeunload仅用于提示,不可发请求;需持续监听输入并防抖写入localStorage/sessionStorage;unload中可用sendBeacon发送小体积日志;刷新后从本地存储恢复草稿。

页面卸载时保存数据,核心难点在于:用户触发刷新或关闭的瞬间,JavaScript 执行环境快速终止,异步请求(如 AJAX)极大概率被中断。直接在 beforeunload 里发请求几乎无效,而 unload 中发起的请求也常因资源释放而失败。真正可行的方案是“提前存 + 最后兜底”,而不是依赖卸载时实时提交。
beforeunload 只能做提示,不能发请求
这个事件设计初衷是让用户确认是否离开,浏览器明确禁止在此阶段执行耗时操作(包括异步网络请求)。即使你调用 fetch 或 XMLHttpRequest,请求大概率不会发出,或发出后立即被中止。它的唯一可靠用途是显示提示语:
- 用
event.returnValue = '内容未保存,确定要离开?'触发浏览器原生对话框 - 不能执行任何逻辑判断或数据发送
- 现代 Chrome 等浏览器已限制该提示语自定义,仅显示统一文案
真正有效的保存必须发生在卸载前
可靠做法是持续监听用户输入,把数据及时暂存到客户端存储中,而非等到最后时刻才行动:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 对表单字段绑定
input或change事件,配合防抖(如 800ms 延迟),避免频繁请求 - 每次变更后,将当前值写入
localStorage(长期可用)或sessionStorage(会话级) - 例如:
localStorage.setItem('form-title', titleInput.value) - 这样即使页面意外关闭,刷新后也能从本地读取并恢复
unload 事件只适合轻量同步操作
unload 在页面完全卸载前触发,但此时 JS 引擎已开始清理,无法保证异步任务完成。它仅适用于:
立即学习“Java免费学习笔记(深入)”;
- 清除定时器、移除事件监听器等清理工作
- 发送极简的同步 Beacon 请求(
navigator.sendBeacon())——这是目前最接近“卸载时发送成功”的标准方案 - Beacon 发送的是小体积数据,不等待响应,由浏览器后台尽力投递,适合日志或状态标记
- 示例:
navigator.sendBeacon('/log', JSON.stringify({action: 'page_exit'}))
刷新/关闭后恢复数据靠本地存储
卸载本身不是保存动作的时机,而是验证和恢复的起点:
- 页面加载时检查
localStorage是否存在未提交的草稿 - 若存在,自动填充表单并标记为“已恢复”
- 用户继续编辑后,新数据覆盖旧缓存;点击正式提交后,清空对应 localStorage 键
- 这样形成闭环:输入 → 缓存 → 提交 → 清理,卸载只是中间一环,不影响数据连续性

















