onbeforeunload是浏览器原生事件,仅在页面卸载(刷新/关闭/导航)时同步触发受限确认对话框,需返回非空字符串,但无法区分刷新与关闭,且现代浏览器要求用户交互后才生效。

刷新页面时触发警告对话框用 onbeforeunload
浏览器原生只允许在页面即将卸载(含刷新、关闭、导航离开)时弹出一个受限的确认对话框,必须用 window.onbeforeunload,不能用 alert 或 confirm 替代——后者会被忽略或直接拦截。
关键点是:你只能设置一个返回值字符串,浏览器会把它拼在默认提示语后面(如 Chrome 显示“要离开此网页吗?……你有未保存的内容”),但 Firefox 完全忽略自定义文本,只显示固定提示。
示例写法:
window.onbeforeunload = function () {
return '你有未保存的内容,确定要刷新吗?';
};
- 只要函数体里有
return一个非空字符串(哪怕只是return ''),对话框就会出现;返回undefined、null或不写return,则不触发 - 该事件无法区分刷新和关闭,也无法阻止用户最终离开——它只是“询问”,用户点“取消”就留下,点“确定”就走
- 现代浏览器(Chrome 88+、Edge 90+)对频繁触发做了限制:只有用户与页面发生过交互(如点击、输入)后,
onbeforeunload才生效;纯加载后立刻刷新不会弹
onbeforeunload 不触发的常见原因
写了代码却没弹窗?大概率卡在这几个地方:
- 页面还没收到用户交互(比如自动刷新脚本、页面刚打开就调
location.reload()),此时浏览器静默忽略onbeforeunload - 函数里用了异步操作(如
fetch、setTimeout)再return,无效——该事件要求同步返回字符串 - 在 iframe 子页面里绑定,但父页面没授权(比如 sandbox 属性没开
allow-scripts) - 使用了单页应用(SPA)路由跳转(如 Vue Router 的
router.push),它不触发onbeforeunload,得靠路由守卫(如beforeEach)手动拦截
想只对刷新生效、避开关闭窗口?做不到
没有可靠方法区分“F5 刷新”和“点击关闭按钮”。网上流传的通过 window.event.clientY 或 screenX 坐标判断,早已失效:Chrome 从 2021 年起移除了这些事件属性,Firefox 从未支持,Safari 表现不一致。硬加这类逻辑只会让部分用户完全收不到提示。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
如果你真需要差异化处理,唯一可行路径是:
- 监听
keydown捕获F5、Ctrl+R、Cmd+R等组合键,提前设个标记变量 - 在
onbeforeunload里检查这个标记,决定是否return字符串 - 但注意:这无法覆盖地址栏回车、右键刷新、菜单栏刷新等所有刷新方式,属于妥协方案
替代方案:别依赖 onbeforeunload 做核心保护
它太不可控——被禁用、被绕过、提示语被裁剪、移动端基本不弹。真正要防数据丢失,得做两件事:
- 把关键状态实时存到
localStorage或sessionStorage,页面重载后自动恢复(比如表单草稿) - 在用户主动点击“提交”或“保存”前,用
confirm()或自定义弹窗二次确认,而不是赌onbeforeunload - 如果项目用框架(React/Vue),优先用其路由守卫或表单脏检查机制,比全局
onbeforeunload更精准
最后提醒一句:onbeforeunload 的存在意义不是“拦住用户”,而是“给一次反悔机会”。把它当最后一道轻量级防线,而不是数据安全的主力。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










