前言

很多人都知道我们在做FineUI控件库,而且我们也做了超过 9 年的时间,在和浏览器无数次的交往中,也发现了多个浏览器自身的BUG,并公开出来方便大家查阅:

这类BUG之所以被大家所深恶痛绝,在于其隐蔽性,很多时候不能用常规的逻辑去分析。另一个原因的开发人员一般都很善良,出现问题总是从自身找原因,很少会怀疑到IDE,浏览器这些开发工具上面来。

事实情况是,浏览器也是开发人员开发的,是个软件就有BUG!

今天公开的这个IE11的Crash BUG也郁闷了我好长时间,今天终于被我逮到了,哈哈哈哈......

发现问题

FineUI(专业版)其实在2016年3月就已经对桌面,平板和手机浏览器进行了适配,并且为手机浏览器增加了动画效果(iOS下的Webkit和Andriod下的Chrome),但是这个CSS3动画仅限于 WebKit 浏览器,并不支持Firefox,Edge,IE11等浏览器。

最近在版本更新中,我想把CSS3动画效果扩展到桌面版的Firefox,Edge和IE11等浏览器,在开发过程中,突然有一天,我发现IE11只要打开调试工具(F12),浏览器就崩溃了,屡试不爽:

IE11下打开页面没问题,但是只要F12打开调试工具,浏览器立马Crash,点击调试按钮,出现的错误信息:

Unhandled exception at 0x754ED8D3 (KernelBase.dll) in iexplore.exe: 0xC0000005: Access violation writing location 0x08090FFC.

貌似是内存写入错误,对于纯前端开发人员来说,遇到这样的问题是一脸无奈:

分析问题

幸运的是,上个版本的FineUI(专业版)没有类似的问题,由于此时已经更新了很多代码,所以下面就进入漫长的代码比对阶段。。。。

。。。。。

。。。。。

。。。。。

经过近一天的分析,问题集中在 CSS3 的 keyframes 关键字和 IFrame 一起使用时出现,我写了两个测试页面:

test1.aspx:

<!DOCTYPE html>

<html>
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<f:PageManager ID="PageManager1" runat="server" /> <iframe src="./test2.aspx"></iframe>
</form>
</body>
</html>

test2.aspx

<!DOCTYPE html>

<html>
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<f:PageManager ID="PageManager1" runat="server" /> <f:Button Text="按钮" runat="server" />
</form>
</body>
</html>

test2.aspx 生成的 HTML 代码如下:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link type="text/css" rel="stylesheet" href="/res.axd?css=f.css&t=636364679643916663"/>
<link type="text/css" rel="stylesheet" href="/res.axd?css=themes.default.theme.css&t=636264594331716901"/> <title> </title></head>
<body>
<form name="form1" method="post" action="test2.aspx" id="form1"> 。。。。。
<div id="ctl02_wrapper" class="f-inline-block"></div> <script type="text/javascript" src="/res.axd?js=f.js&t=636364680829342350"></script>
<script type="text/javascript" src="/res.axd?js=lang.zh_CN.js&t=636364679651261140"></script> <script type="text/javascript">
//<![CDATA[
F.load(function () {
F.f_init({
theme: 'default',
baseUrl : '/',
displayMode: 'normal',
_version: '3.7.0',
_customId: '0oOOoo'
});
F.f_pagemanager = new F.Component({
f_state: {},
id: 'PageManager1',
name: 'PageManager1',
hidden: true
});
var f1 = new F.Button({
f_state: {},
id: 'ctl02',
name: 'ctl02',
renderTo: '#ctl02_wrapper',
text: '按钮',
handler: function () {
F.f_disable('ctl02');
__doPostBack('ctl02', '');
}
});
});//]]>
</script>
</form>
</body>
</html>

为了方便调试,我们把 test2.aspx 中引用的 CSS 文件下载下来,并更新 test2.aspx 为:

<!DOCTYPE html>
<html>
<head>
<title></title>
<link type="text/css" rel="stylesheet" href="/res.axd?css=f.css&t=636364679643916663"/> </head>
<body> </body>
</html>

此时问题依旧,F12浏览器照样Crash。遵循怀疑一切的原则,我们把 res.axd 加载的资源文件下载到本地 f.css,并把上面的 test2.aspx 改为:

<!DOCTYPE html>
<html>
<head>
<title></title>
<link type="text/css" rel="stylesheet" href="f.css"/> </head>
<body> </body>
</html>

此时问题消失!!所以我们不得不怀疑 res.axd?css=f.css 和 f.css 的响应头不一样,因为两者的内容完全相同。

事后看来这一怀疑是错误的,事后诸葛每个人都会做,但真正遇到类似的无厘头BUG时,还是怀疑一切的好,我们甚至比较两者的响应头,唯一的不同是:

res.axd?css=f.css:

Content-Type:text/css; charset=utf-8

f.css:

Content-Type:text/css

然后,我们尝试修改的 res.axd?css=f.css,使其和 f.css 的完全一样,还是不行,浏览器照样崩溃。

郁闷中....

此路不通

既然 res.axd?css=f.css 和 f.css  的响应头完全相同,内容完全相同,但是效果却截然不同,一个导致IE11崩溃,而另一个不会!

好吧,我们只好怀疑两者的URL不同了,再来仔细对比下:

<link type="text/css" rel="stylesheet" href="/res.axd?css=f.css&t=636364679643916663"/>   (IE11打开调试工具时崩溃)

<link type="text/css" rel="stylesheet" href="f.css"/>   (IE11打开调试工具时不崩溃)

难道是。。。难道是。。。难道是。。。难道是。。。难道是。。。

一个最不可能的念头在我脑海里出现,难道是第一个URL太长了???

不要搞笑,这怎么可能呢,Windows文件的路径好像有长度限制,但,但,但,但,这个URL真的不长啊。。。。

不可能。。。算了。。。不是这个地方的问题。。。。

。。。。。

。。。。。

。。。。。

不行,还是把自己当个傻子,我就把URL改短一点,看是否有问题,我很坎坷的删除了最后一个数字 3,把:

/res.axd?css=f.css&t=636364679643916663

改为:

/res.axd?css=f.css&t=63636467964391666

问题消失!!!!!

我都要惊呼了,难道真是URL太长了,还就多个一个字符!!!

一阵兴奋之后,是一阵郁闷,因为我把URL加长了,同样问题消失:

/res.axd?css=f.css&t=636364679643916663897978783784328467326473624763274632764732

再次思考

好吧,我是有点语无伦次,在经历多次怀疑,否定,再怀疑,再否定之后,我们终于能够重现问题了,其实很简单:

IFrame中的这个CSS文件和父页面中的CSS文件URL相同导致的(而不是URL长度的问题)!

至此,我们可以简单的重现如下(下载可重现压缩包,IE11打开后,F12直接崩溃):

test1.html

<!DOCTYPE html>
<html>
<head>
<title></title>
<link type="text/css" rel="stylesheet" href="fineui.css" /> </head>
<body>
<iframe src="./test2.html"></iframe>
</body>
</html>

test2.html:

<!DOCTYPE html>
<html>
<head>
<title></title>
<link type="text/css" rel="stylesheet" href="fineui.css" /> </head>
<body> </body>
</html>

fineui.css:

@keyframes slideLeftIn {
0% { opacity: 0; }
100% { opacity: 1; }
}

在IE11中打开 test1.html,F12打开调试窗口,浏览器立马崩溃!!!

说好的《三招搞死你的IE11》

后来发现,这个问题不用 iframe 也能重现,只要满足两个条件,立马崩溃:

  1. 页面加载同一个CSS文件两次
  2. CSS文件中包含 @keyframes 的定义

下面给出一个最简单的测试例子(下载可重现压缩包,IE11打开后,F12直接崩溃):

第一步:新建一个 test3.html 文件:

<!DOCTYPE html>
<html>
<head>
<title></title>
<link type="text/css" rel="stylesheet" href="fineui.css" />
<link type="text/css" rel="stylesheet" href="fineui.css" /> </head>
<body> </body>
</html>

第二步:相同目录新建一个 fineui.css 文件:

@keyframes slideLeftIn {
0% { opacity: 0; }
100% { opacity: 1; }
}

第三步:在IE11中打开上述页面,F12调出调试窗口,IE立马崩溃!不服来辩

解决问题

暂无!

没办法,IE11自身的BUG,除非你不用IE11,或者绕行。

绕行有几个简单的办法:

  1. CSS文件中不要包含 @keyframes 关键字(这个不可能,特别是希望IE11下支持CSS3动画效果的)
  2. 不要在页面中引用同一个CSS文件两次(正确情况下没人会引用两次,而IFrame中就不可避免了!)
  3. 主页面和IFrame中引用同一个CSS文件,给CSS文件加个随机后缀(影响浏览器缓存,正式环境不建议用)

好吧,如果你真正需要 @keyframes 和 iframe 两个元素时,还真没办法避免这个问题。

反馈

由于 Windows 操作系统和IE的版本众多,我这边使用的版本:

1. Windows 10 家庭版

2. IE11版本如下:

如果你用我们提供的《三步搞死你的IE11,浏览器打开后,F12直接崩溃》附件,能够本机重现,请评论提供如下信息:

1. Windows 版本

2. IE11 版本

【原创】IE11惊现无厘头Crash BUG(三招搞死你的IE11,并提供可重现代码)!的更多相关文章

  1. 【已更新】【原创】Chrome53 最新版惊现无厘头卡死 BUG!

    发现问题 今天有客户向我们反馈了一个BUG:一个页面在IE.FireFox.Chrome52中能正常运行,但是在最新版的Chrome53中显示不了??? 习惯性的,我们需要客户提供页面在浏览器中的HT ...

  2. 【原创】三招搞死你的IE11,可重现代码下载(IE Crash keyframes iframe)!

    前言 很多人都知道我们在做FineUI控件库,而且我们也做了超过 9 年的时间,在和浏览器无数次的交往中,也发现了多个浏览器自身的BUG,并公开出来方便大家查阅: 分享IE7一个神奇的BUG(不是封闭 ...

  3. 记录一次无厘头的粗心失误——java后台报错:Unknown column 'xxx' in 'field list'

    原因: sql文件马虎,直接用错了仓库.用的不是程序调用的仓库.而自己pojo和mapper还是采用Mybatis的逆向工程生成的.当时搞得很无厘头. 解决方案: sql用到程序指定的仓库就行啦. 总 ...

  4. IIS7.5中调试.Net 4.0网站出现无厘头500错误的解决办法 (转)

    刚刚 部署了ii7的dll的有x86写的,就会出现以下这样的问题 iis 7 x86,Could not load file or assembly 'Name' or one of its depe ...

  5. 分享关于学习new BufferedWriter()方法时常遇到的一个无厘头的问题

    今天在学习IO的过程中,关于处理流BufferedWriter的使用时,遇到了一个很犯二但是又会让初学者经常没有避免的问题,百度后才发现有人和我一样二,这还是对java基础掌握得不牢固的原因啊. 首先 ...

  6. 【有意思的BUG】客户端无厘头 已连网的场景初始化太慢 未连网的场景异常崩溃

    客户端 已连网的场景初始化太慢 当在未连接internet的时候,打开某些APP,会比较迅速地初始化进入到主页面. 但是当我在已经连接了internet的时候,打开某些APP,有些会初始化很久!!!! ...

  7. [原创][开源]C# Winform DPI自适应方案,SunnyUI三步搞定

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  8. [原创]反汇编之一:和Taskmgr过不去篇(无厘头版)

    原文链接:和Taskmgr过不去篇(无厘头版) Hook入门级文章,主要想培养一下偶写文章的感觉,老鸟无视…我想看看技术文章能不能无厘头的写,如果效果不错的话,准备更上一层-----用我的原创漫画表达 ...

  9. 岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯

    岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯 看过了QQ和360斗争的开端高潮,当然现在还不能说这场斗争已经结束,在我看来这次的事件未尝不是一个适 ...

随机推荐

  1. centos5.5下mangodb启动报错glibc

    mangodb启动报错glibc找不到(centos5.5) 报错形式 [root@test-172-16-0-139-ip mongodb-server]# /data/mongodb-server ...

  2. Rhythmbox音乐播放器常见问题

    一.歌名中文乱码 对于所有用gstreamer做后端的播放器,如Rhythmbox, 设置如下的环境变量后即可正确读取mp3中GBK编码的id3 tag. export GST_ID3_TAG_ENC ...

  3. [转]TOMCAT配置多端口

    一.Tomcat 安装后本身提供了一个server,端口配置默认是8080,对应目录为:..\Tomcat 6.0\webapps二.Tomcat 6.0 配置多个端口,其实也就是给Tomcat增加几 ...

  4. 短信发送接口被恶意访问的网络攻击事件(三)定位恶意IP的日志分析脚本

    前言 承接前文<短信发送接口被恶意访问的网络攻击事件(二)肉搏战-阻止恶意请求>,文中有讲到一个定位非法IP的shell脚本,现在就来公布一下吧,并没有什么技术难度,只是当时花了些时间去写 ...

  5. Akka(9): 分布式运算:Remoting-远程构建式

    上篇我们讨论了Akka-Remoting.我们说Akka-Remoting是一种点对点的通讯方式,能使两个不同JVM上Akka-ActorSystem上的两个Actor之间可以相互沟通.Akka-Re ...

  6. MongoDB-配置翻译

    Configuration File(配置文件) File Format(文件格式) Use the Configuration File(使用配置文件) Core Options(核心设置) sys ...

  7. ORA-00245问题总结

    (1)问题描述 在进行数据库归档备份时(备份归档日志文件和控制文件),有时成功,有时失败,失败报错如下: RMAN-00571: =================================== ...

  8. [命令行] curl查询公网出口IP

    转载:http://blog.csdn.net/orangleliu/article/details/51994513 不管是在家里还是办公室,或者是公司的主机,很多时候都是在内网中,也就是说很多都是 ...

  9. 打造一个简单的Java字节码反编译器

    简介 本文示范了一种反编译Java字节码的方法,首先通过解析class文件,然后将解析的结果转成java代码.但是本文并没有覆盖所有的class文件的特性和指令,只针对部分规范进行解析. 所有的代码代 ...

  10. 微信开发之获取jsapi_ticket

    一.获取流程 1.获取 access_token 2.通过access_token换取 jsapi_ticket 3.签名算法 签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有 ...