onbeforeunload不能安全保存草稿,仅能同步判断未保存状态并触发浏览器统一提示;真正保存必须依赖防抖(800ms)+localstorage主动写入,且需内容比对、输入法过滤、键名隔离。

onbeforeunload 里根本不能安全保存草稿
它不支持任何异步操作,也没有足够时间执行 localStorage 写入以外的逻辑。现代浏览器只给约 50ms 执行窗口,且要求 handler 必须同步返回字符串——await saveDraft()、fetch()、indexedDB.put() 全部失效,连 console.log() 都可能被截断。
为什么很多人误以为它能存草稿
常见错觉来自两个地方:一是把“弹出提示”当成“已保存”,实际提示只是浏览器默认行为;二是草稿看似恢复了,其实是之前防抖写入的残留,并非 beforeunload 功劳。
- Chrome 98+ 已屏蔽自定义提示文案,只显示统一警告,用户无法得知是否真存了
- Safari 在 iframe 或隐私模式下可能完全不触发该事件
- 进程被强杀、系统断电、浏览器崩溃时,
beforeunload根本不会执行
它唯一可靠用途:只做布尔判断 + 同步提示
真正能做的只有一件事:检查是否有未保存变更,然后返回字符串触发浏览器提示。必须提前维护一个状态标志位:
- 输入开始时设
hasUnsavedChanges = true - 每次防抖保存成功后设
hasUnsavedChanges = false -
beforeunload中仅做if (hasUnsavedChanges) return '内容尚未保存'
注意:返回值不是提示语,而是“是否需要确认离开”的信号;现代浏览器会忽略字符串内容,只用它决定是否弹窗。
真正保存草稿的时机必须提前完成
草稿落盘只能靠防抖后的 localStorage.setItem() 主动写入,且必须满足三个条件:
- 写入前比对内容是否变化:
if (prevValue !== currentValue),避免无效 I/O - 跳过输入法中间态:
if (event.isComposing) return - 键名带上下文隔离:
draft-${form.id}-${location.pathname},防止多表单覆盖
防抖延迟建议 800ms,太短(如 300ms)容易被中文输入法打断,太长(如 2s)则崩溃时丢失过多内容。最后那一次写入,才是你真正能依赖的“最后一版”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











