iOS7 中 Safari 的一个离奇 Bug

8年以前 | 1988 次阅读

这个 Bug 是我由同事发现并确认的,一开始我还不相信 Apple 会犯这么低级的错误。截止到目前,所有版本的 iOS7(包括最新的 7.0.2),无论是运行在 iPhone、iPad 上,还是 iPod touch 都有问题。简而言之,这个 Bug 是「某种情况下,Safari 中的 alert、confirm 和 prompt 方法都坏掉。而且重启 Safari 之前,即使刷新或新建 Tab,这个 Bug 始终存在」。至于是什么情况下,会坏成什么样,请继续往下看。

触发条件

经过分析,以下代码会触发 iOS7 自带 Safari 的这个 Bug:


var iframe = document.createElement("iframe");

    iframe.src = "xxx:yyy";
    document.body.insertBefore(iframe, document.body.childNodes[0]);
    
    confirm('?');
    

也就是说,iOS7 中,在页面插入 iframe 时使用了 Safari 不认识的协议;紧接着调用 window.confirm 方法,就会触发这个 Bug。

现象

上面的代码,会几乎同时弹出两个系统浮层:一个是「无法打开页面」提示,一个是 confirm 对话框。正常情况下,confirm 会停止执行后续代码,等待用户选择 Cancel/OK,并返回用户选择的布尔值:

![confirm](https://codingsky.oss-cn-hangzhou.aliyuncs.com/cdn/codingsky/upload /img/blog/8dfac10344ca4c24ebce9d063e3e3b9f.png)(普通的 confirm。链接)

但在触发了 Bug 的代码中,confirm 会直接返回 false,并继续执行后续代码。虽然也显示对话框,但无论选哪个选项都一样----代码早就执行过了:

![broken confirm](https://codingsky.oss-cn-hangzhou.aliyuncs.com/cdn/codingsky /upload/img/blog/8dfac10344ca4c24ebce9d063e3e3b9f.png)(坏掉的 confirm。链接)

更为严重的是:只要激活了这个 Bug,即使新建 Tab 访问其它正常页面,confirm、alert 或 prompt 仍然不停止执行代码,仍然得不到 confirm 和 prompt 的正确返回值(它俩返回值始终是 false 和 null)。

![broken confirm 2](https://codingsky.oss-cn-hangzhou.aliyuncs.com/cdn/codings ky/upload/img/blog/8dfac10344ca4c24ebce9d063e3e3b9f.png)

双击 Home 键杀死 Safari,重新打开 Safari 访问正常页面,confirm 等方法才会正常。

结论

我把这个 Bug 汇报给了 Apple,到目前为止没有收到任何回复。目前我们能做的不外乎两点:1)避免使用「触发条件」这一小节提到的代码;2)由于这个 Bug 影响的是整个 Safari,所以尽量不要使用原生 alert、confirm 和 prompt,自己实现具有这些功能的浮层。

update @ 2013.10.24,在更新到 iOS 7.0.3(11B511) 的 iPhone 4s 上测试,本文描述的问题仍未修复。

update @ 2013.11.15,在更新到 iOS 7.0.4(11B554a) 的 iPhone 4s 上测试,本文描述的问题仍未修复。

专题「浏览器」的其他文章 »

  • iOS 10 Safari 视频播放新政策 (Oct 07, 2016)
  • Chrome 中 scrollingElement 的变化 (Apr 16, 2016)
  • 域名小知识:Public Suffix List (Nov 28, 2015)
  • window.opener.location 安全风险讨论 (Oct 09, 2015)
  • 使用 SRI 增强 localStorage 代码安全 (Sep 26, 2015)
  • Subresource Integrity 介绍 (Sep 23, 2015)
  • 移动 Web 与 JavaScript 定时器 (Mar 27, 2014)
  • Chrome 和 Web Fonts 二三事 (Mar 24, 2014)
  • Webkit 异步加载 CSS 的奇怪现象 (Dec 25, 2013)
  • 小成本实现部分选中的复选框 (Dec 22, 2013)