现阶段来源于 iframe(不管是否跨域的) 的 JS 弹窗 (alert/confirm/prompt) 是令人困惑, 因为它出现的时候看起来像浏览器自己的弹窗.
近期, Chrome 92 进行了发布, 我们来看看 Chrome 92 中提及的一个影响比较大的破坏性改动.
https://www.chromestatus.com/feature/5148698084376576
对于来自跨域的 iframes 将被禁止 alert,confirm 和 prompt 等功能.
首先我们先来看看 Chrome 对这个破坏性的动机的官方解释:
如果不明白跨域的可以看我这篇文章: 10 种跨域解决方案(附终极方案)
"现阶段来源于 iframe(不管是否跨域的) 的 JS 弹窗 (alert/confirm/prompt) 是令人困惑, 因为它出现的时候看起来像浏览器自己的弹窗. 这容器欺骗用户 (尤其是 window.prompt), 例如 iframe 站点假装特定消息来自 Chrome(例如 1,2,3). 通过在消息前加上"say..." 来掩饰这些欺骗行为. 然而, 当这些 alerts 来自跨域 iframe 时, UI 会更加混乱, 因为 Chrome 试图解释对话框不是来自浏览器本身或顶级页面. 一方面由于跨域 iframe JS 对话框的使用率较低, 从事实来看, 站点的主要功能通常不需要使用 JS 对话框时, 另一方面难以可靠地解释对话框的来源, 因此我们建议删除跨域 iframe 中的 JS 对话框 . 这也将避免我们将通过删除主机名提示, 或者将对话框移动到内容区域的中心, 来使对话框更明显地成为页面的一部分来明确对话框的含义(这个对话框不是由浏览器发出的). 因此当出现跨域 iframe 弹窗(alert/confirm/prompt) 将会被阻止, 否则这些子 iframes 可能会假装父页面的对话框.
为了实际的演示, 我们先来看看旧版浏览器的效果.
有些运营商或者插件劫持你的页面或者广告, 会往你的页面插入一些 iframe 之类的元素. 以 alert 为例:
- // localhost:5000
- alert("百度提醒: 恭喜中奖!")
我们来模拟一下这个过程:
这个影响可能没那么严重, 但是会使用当我们使用 Windows.confirm/Windows.prompt 来插入到页面的时候, 可就麻烦大了, 因为他们是可交换的.
- const sign = prompt("百度提醒: 用户信息即将过期请确认你的密码");
- console.log(sign);
也许以上两个例子比较简单, 绝大多数人都不会上当, 但是如果换成一个域名非常相似, 手段更加高明的子网页, 那么其中的安全隐患可想而知.
因为当我们升级了 Chrome 92 之后, 这个问题便得以迎刃而解了.
可以看到, 当往主站中插入一个 iframe , 里面是有弹窗的, 但是主站根本不会理会这个弹窗.
因此当存在跨域的子 iframe , 它的 alert/confirm/prompt 将会失效. 这个改动带来安全性的同时也带来了很多老系统的兼容性问题.
例如内部的 OA 系统, 就是嵌套一些开放性的页面提供给第三方调用, 页面交互就是以 prompt/confirm 进行确认的, 那么工程师就要进行相应的改动了.
提交工单
- btn.onclick = () => {
- const msg = "您真的确定要提交吗?\n\n 请确认!";
- if (confirm(msg) == true) {
- axios.post('xxxx')
- return true;
- } else {
- return false;
- }
- }
安全是一把双刃剑, 有些时候更安全了, 就会变得麻烦.
例如跨域请求问题, 几乎曾让每个前端工程师都抓狂过, 也许还会抱怨为什么还有跨域这种东西来影响我们的开发的?
再比如, 类似于现在的安全验证, 除了输入密码, 还得设置各种密保, 或者绑定邮箱啊手机啊类似的种种, 都是属于安全范畴, 虽然对用户来说产品的链路变得更加长了, 但是它更安全了.
来源: http://os.51cto.com/art/202108/676349.htm