不少人都知道咱們在作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 版本