不少人都知道咱们在作FineUI控件库,并且咱们也作了超过 9 年的时间,在和浏览器无数次的交往中,也发现了多个浏览器自身的BUG,并公开出来方便你们查阅:javascript
这类BUG之因此被你们所深恶痛绝,在于其隐蔽性,不少时候不能用常规的逻辑去分析。另外一个缘由的开发人员通常都很善良,出现问题老是从自身找缘由,不多会怀疑到IDE,浏览器这些开发工具上面来。css
事实状况是,浏览器也是开发人员开发的,是个软件就有BUG!html
今天公开的这个IE11的Crash BUG也郁闷了我好长时间,今天终于被我逮到了,哈哈哈哈......前端
FineUI(专业版)其实在2016年3月就已经对桌面,平板和手机浏览器进行了适配,而且为手机浏览器增长了动画效果(iOS下的Webkit和Andriod下的Chrome),可是这个CSS3动画仅限于 WebKit 浏览器,并不支持Firefox,Edge,IE11等浏览器。java
最近在版本更新中,我想把CSS3动画效果扩展到桌面版的Firefox,Edge和IE11等浏览器,在开发过程当中,忽然有一天,我发现IE11只要打开调试工具(F12),浏览器就崩溃了,屡试不爽:浏览器
IE11下打开页面没问题,可是只要F12打开调试工具,浏览器立马Crash,点击调试按钮,出现的错误信息:缓存
Unhandled exception at 0x754ED8D3 (KernelBase.dll) in iexplore.exe: 0xC0000005: Access violation writing location 0x08090FFC.app
貌似是内存写入错误,对于纯前端开发人员来讲,遇到这样的问题是一脸无奈:ide
幸运的是,上个版本的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打开调试窗口,浏览器立马崩溃!!!
后来发现,这个问题不用 iframe 也能重现,只要知足两个条件,立马崩溃:
下面给出一个最简单的测试例子(下载可重现压缩包,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,或者绕行。
绕行有几个简单的办法:
好吧,若是你真正须要 @keyframes 和 iframe 两个元素时,还真没办法避免这个问题。
因为 Windows 操做系统和IE的版本众多,我这边使用的版本:
1. Windows 10 家庭版
2. IE11版本以下:
若是你用咱们提供的《三步搞死你的IE11,浏览器打开后,F12直接崩溃》附件,可以本机重现,请评论提供以下信息:
1. Windows 版本
2. IE11 版本