❗ 本文最后更新于 4062 天前,文中所描述的信息可能已发生改变,请谨慎使用。
这个 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。链接)
但在触发了 Bug 的代码中,confirm 会直接返回 false,并继续执行后续代码。虽然也显示对话框,但无论选哪个选项都一样——代码早就执行过了:
(坏掉的 confirm。链接)
更为严重的是:只要激活了这个 Bug,即使新建 Tab 访问其它正常页面,confirm、alert 或 prompt 仍然不停止执行代码,仍然得不到 confirm 和 prompt 的正确返回值(它俩返回值始终是 false 和 null)。
双击 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 上测试,本文描述的问题仍未修复。
本文链接:https://imququ.com/post/a-bug-with-safari-in-ios7.html,参与评论 »
--EOF--
发表于 2013-10-08 15:53:22,并被添加「Bug、Safari、iOS」标签。查看本文 Markdown 版本 »
专题「浏览器」的其他文章 »
- 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)
Comments
Waline 评论加载中...