文章出處

前言

很多人都知道我們在做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 版本

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()