Chromium 的弹窗机制

JavaScript 弹窗的历史

JavaScript 诞生于1995年,在最初的版本里便包含了三个挂载到 window 对象上的弹窗方法 alert()confirm(), 和 prompt()

这种阻断式的弹窗 API 在当时是没有问题的,但在异步操作流行的今天便不合时宜了。因为 JavaScript 引擎需要中断执行来等待用户的反馈,关键这个弹窗是原生的还不是网页里的。 正因为是原生的弹窗,所以经常被利用来 伤害 我们的 用户

鉴于此,Chromium 团队强烈建议你不要使用这类弹窗。

替代方案

对于弹窗需求其实我们有很多其他的选择。

对于 alert()/confirm()/prompt() 我们有很多替代的选择。 譬如需要弹个通知消息时(日历应用)可以用 Notifications API。 获取用户输入可以用 HTML 中的 <dialog> 元素 。 对于 XSS proofs-of-concept 则可用 console.log(document.origin)

至于 onbeforeunload 这个事件,它已经变得不可靠了。正如 Ilya Grigorik 所指出的那样, “在移动端平台上,你不能指望 pagehidebeforeunloadunload 这些事件会被触发。” 如果想在此类情况下保存一些数据,可以用 Page Visibility API

变更

Chrome 51 中移除了对 onbeforeunload 的支持。(Safari 9.1 and in Firefox 4 中也移除了的。)

alert()/confirm()/prompt() 的表现进行了改变。不再作为顶级的原生弹窗而存在,当弹窗所在的浏览器标签被切走后, 他们会自动消失。 (Safari 9.1 已经这样做了。) 这个变更在 canary 和 dev 版本中全部开启, 而在 beta 和稳定版中则是部分开启,但在之后肯定是会全部开启的。

对于 beforeunload 弹窗,目前的计划是必需有用户有相应的交互才让它显示。(但 beforeunload 事件的广播不会受影响。) 这使得 Chromium 在表现上和 Firefox 统一了,后者在 Firefox 44 中做了此项修改。

由于以上这些变更,如果你的站点中使用了弹窗,我们强烈建议你使用上文中提到的备选方案,以免功能受到影响。