【原創】三招搞死你的IE11,可重現代碼下載(IE Crash keyframes iframe)!

前言

不少人都知道咱們在作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打開調試窗口,瀏覽器立馬崩潰!!!

 

 

說好的《三招搞死你的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 版本

相關文章
相關標籤/搜索