【JavaScript吉光片羽】遭遇IE8

最初對作兼容性的認知只停留在UI層面,但其實UI層面都還好,由於畢竟你能夠直接看得見現象,更爲重要的是在JavaScript層面,由於這個部分涉及到功能性,前者最可能是體驗性的問題。下面扯一下這幾天遇到的IE8相關的兼容性問題。php

1.全部$.ajax失效

剛開始看到的現象是IE8/9頁面切到了留言頁面,沒有進入正常流程。打開fiddler都沒抓到請求,奇怪了,打出$.ajax error方法中的返回值。xhr.status的值都是0,原來請求沒有發出去。心想:怎麼沒有發出去呢,難道是跨域問題,不對啊,服務端已經容許跨域了。後來一查(IE8/9下的跨域資源請求),原來請求被IE8/9阻止了,因此服務端容許跨域了也沒有用。當時網上有兩種辦法,1個是設置瀏覽器,容許經過域訪問數據源。2個是加入一個js插件,也就是讓IE8/9/10走IE本身支持的XDomainRequest發送請求。第一個方法只能玩玩,不可能讓用戶去操做套路那麼深的步驟。第二個方法github上有兩套js。css

引用後都不用改代碼,剛開始還有點小激動。
<!--[if (IE 8)|(IE 9)]><script src="Js/jQuery.XDOmainRequest.js"></script><![endif]-->

加上去一看,請求發過去了,界面進入了正常流程。but,又發現返回的值不對,說與服務端,服務端說你的值沒傳過來,怎麼可能,代碼都沒動,原來這個XDomainRequest是參數走的header,先天性缺乏contentType,沒有參數的請求返回是正確的,有參數的後臺就沒有讀到。又尋思着難道要後臺改代碼,支持一下這種方式?我遲疑了。而後就到羣裏和隊友們討論下。你們給出的方案就是,用Nginx配置個代理就行了。啊,一時激動的有點難以言表。繞了一大圈,啥都不用改,服務器上配置下就行了。由於,既然是跨域問題,最根本的方法就是讓它不用跨域了。這種先後端分離的架構,網站(html)和api都是不一樣的域名.html

location /api/{
        proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass_request_headers      on;
            proxy_pass  http://11.111.111.11/api/;
}

因此這纔是最佳解決方案。當時就想,本身對跨域的認知不足,遇到問題都是橫向的找辦法,沒有往上層想。仍是有給力的隊友。這個問題stackoverflow也有討論:前端

2.消息怎麼變長了

這個問題的現象看起來很神奇,用戶在IE8上發送長消息(好比1000字)開始能顯示在對話框中,可是一刷新就沒了。別的瀏覽器刷新後長消息都還在。我打開日誌,ajax是進入了成功回調,可是返回值有文字提示:'消息過長被阻止'。也就是說我當作功回調了就立馬顯示到界面上了,可是並無成功,因此刷新以後拿不到那條消息。ajax的succes只是表明請求成功,並不表明調用api對了。這是我犯得低級錯誤,沒有和api同事確認。但爲何消息會變長呢,一開始把字數調500,ie8可以發了。說明請求確實變長了。打開日誌發現。漢字都被轉碼了。好比:node

    var data={name:"博客園"}
     alert(JSON.stringify(data));

IE8會獲得jquery

也就是說本質上是json轉義的問題。以前給ie8加了一個json2.c++

<!--[if IE 8]><script src="json2.min.js"></script><![endif]-->  

看來還不行。換成json3,1000字也正常了。git

<!--[if IE 8]><script src="json3.min.js"></script><![endif]--> 

3.flash檢測

若是你想準確的判斷用戶的IE到底有沒flash。得用SWFObject對象。github

/*!    SWFObject v2.3.20130521 <http://github.com/swfobject/swfobject>
    is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject = function () {
    var D = "undefined", r = "object", T = "Shockwave Flash", Z = "ShockwaveFlash.ShockwaveFlash", q = "application/x-shockwave-flash", S = "SWFObjectExprInst", x = "onreadystatechange", Q = window, h = document, t = navigator, V = false, X = [], o = [], P = [], K = [], I, p, E, B, L = false, a = false, m, G, j = true, l = false, O = function () { var ad = typeof h.getElementById != D && typeof h.getElementsByTagName != D && typeof h.createElement != D, ak = t.userAgent.toLowerCase(), ab = t.platform.toLowerCase(), ah = ab ? /win/.test(ab) : /win/.test(ak), af = ab ? /mac/.test(ab) : /mac/.test(ak), ai = /webkit/.test(ak) ? parseFloat(ak.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, aa = t.appName === "Microsoft Internet Explorer", aj = [0, 0, 0], ae = null; if (typeof t.plugins != D && typeof t.plugins[T] == r) { ae = t.plugins[T].description; if (ae && (typeof t.mimeTypes != D && t.mimeTypes[q] && t.mimeTypes[q].enabledPlugin)) { V = true; aa = false; ae = ae.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); aj[0] = n(ae.replace(/^(.*)\..*$/, "$1")); aj[1] = n(ae.replace(/^.*\.(.*)\s.*$/, "$1")); aj[2] = /[a-zA-Z]/.test(ae) ? n(ae.replace(/^.*[a-zA-Z]+(.*)$/, "$1")) : 0 } } else { if (typeof Q.ActiveXObject != D) { try { var ag = new ActiveXObject(Z); if (ag) { ae = ag.GetVariable("$version"); if (ae) { aa = true; ae = ae.split(" ")[1].split(","); aj = [n(ae[0]), n(ae[1]), n(ae[2])] } } } catch (ac) { } } } return { w3: ad, pv: aj, wk: ai, ie: aa, win: ah, mac: af } }(), i = function () { if (!O.w3) { return } if ((typeof h.readyState != D && (h.readyState === "complete" || h.readyState === "interactive")) || (typeof h.readyState == D && (h.getElementsByTagName("body")[0] || h.body))) { f() } if (!L) { if (typeof h.addEventListener != D) { h.addEventListener("DOMContentLoaded", f, false) } if (O.ie) { h.attachEvent(x, function aa() { if (h.readyState == "complete") { h.detachEvent(x, aa); f() } }); if (Q == top) { (function ac() { if (L) { return } try { h.documentElement.doScroll("left") } catch (ad) { setTimeout(ac, 0); return } f() }()) } } if (O.wk) { (function ab() { if (L) { return } if (!/loaded|complete/.test(h.readyState)) { setTimeout(ab, 0); return } f() }()) } } }(); function f() { if (L || !document.getElementsByTagName("body")[0]) { return } try { var ac, ad = C("span"); ad.style.display = "none"; ac = h.getElementsByTagName("body")[0].appendChild(ad); ac.parentNode.removeChild(ac); ac = null; ad = null } catch (ae) { return } L = true; var aa = X.length; for (var ab = 0; ab < aa; ab++) { X[ab]() } } function M(aa) { if (L) { aa() } else { X[X.length] = aa } } function s(ab) { if (typeof Q.addEventListener != D) { Q.addEventListener("load", ab, false) } else { if (typeof h.addEventListener != D) { h.addEventListener("load", ab, false) } else { if (typeof Q.attachEvent != D) { g(Q, "onload", ab) } else { if (typeof Q.onload == "function") { var aa = Q.onload; Q.onload = function () { aa(); ab() } } else { Q.onload = ab } } } } } function Y() { var aa = h.getElementsByTagName("body")[0]; var ae = C(r); ae.setAttribute("style", "visibility: hidden;"); ae.setAttribute("type", q); var ad = aa.appendChild(ae); if (ad) { var ac = 0; (function ab() { if (typeof ad.GetVariable != D) { try { var ag = ad.GetVariable("$version"); if (ag) { ag = ag.split(" ")[1].split(","); O.pv = [n(ag[0]), n(ag[1]), n(ag[2])] } } catch (af) { O.pv = [8, 0, 0] } } else { if (ac < 10) { ac++; setTimeout(ab, 10); return } } aa.removeChild(ae); ad = null; H() }()) } else { H() } } function H() { var aj = o.length; if (aj > 0) { for (var ai = 0; ai < aj; ai++) { var ab = o[ai].id; var ae = o[ai].callbackFn; var ad = { success: false, id: ab }; if (O.pv[0] > 0) { var ah = c(ab); if (ah) { if (F(o[ai].swfVersion) && !(O.wk && O.wk < 312)) { w(ab, true); if (ae) { ad.success = true; ad.ref = z(ab); ad.id = ab; ae(ad) } } else { if (o[ai].expressInstall && A()) { var al = {}; al.data = o[ai].expressInstall; al.width = ah.getAttribute("width") || "0"; al.height = ah.getAttribute("height") || "0"; if (ah.getAttribute("class")) { al.styleclass = ah.getAttribute("class") } if (ah.getAttribute("align")) { al.align = ah.getAttribute("align") } var ak = {}; var aa = ah.getElementsByTagName("param"); var af = aa.length; for (var ag = 0; ag < af; ag++) { if (aa[ag].getAttribute("name").toLowerCase() != "movie") { ak[aa[ag].getAttribute("name")] = aa[ag].getAttribute("value") } } R(al, ak, ab, ae) } else { b(ah); if (ae) { ae(ad) } } } } } else { w(ab, true); if (ae) { var ac = z(ab); if (ac && typeof ac.SetVariable != D) { ad.success = true; ad.ref = ac; ad.id = ac.id } ae(ad) } } } } } X[0] = function () { if (V) { Y() } else { H() } }; function z(ac) { var aa = null, ab = c(ac); if (ab && ab.nodeName.toUpperCase() === "OBJECT") { if (typeof ab.SetVariable !== D) { aa = ab } else { aa = ab.getElementsByTagName(r)[0] || ab } } return aa } function A() { return !a && F("6.0.65") && (O.win || O.mac) && !(O.wk && O.wk < 312) } function R(ad, ae, aa, ac) {
        var ah = c(aa); aa = W(aa); a = true; E = ac || null; B = { success: false, id: aa }; if (ah) {
            if (ah.nodeName.toUpperCase() == "OBJECT") { I = J(ah); p = null } else { I = ah; p = aa } ad.id = S; if (typeof ad.width == D || (!/%$/.test(ad.width) && n(ad.width) < 310)) { ad.width = "310" } if (typeof ad.height == D || (!/%$/.test(ad.height) && n(ad.height) < 137)) { ad.height = "137" } var ag = O.ie ? "ActiveX" : "PlugIn", af = "MMredirectURL=" + encodeURIComponent(Q.location.toString().replace(/&/g, "%26")) + "&MMplayerType=" + ag + "&MMdoctitle=" + encodeURIComponent(h.title.slice(0, 47) + " - Flash Player Installation"); if (typeof ae.flashvars != D) { ae.flashvars += "&" + af } else { ae.flashvars = af } if (O.ie && ah.readyState != 4) {
                var ab = C("div");
                aa += "SWFObjectNew"; ab.setAttribute("id", aa); ah.parentNode.insertBefore(ab, ah); ah.style.display = "none"; y(ah)
            } u(ad, ae, aa)
        }
    } function b(ab) { if (O.ie && ab.readyState != 4) { ab.style.display = "none"; var aa = C("div"); ab.parentNode.insertBefore(aa, ab); aa.parentNode.replaceChild(J(ab), aa); y(ab) } else { ab.parentNode.replaceChild(J(ab), ab) } } function J(af) { var ae = C("div"); if (O.win && O.ie) { ae.innerHTML = af.innerHTML } else { var ab = af.getElementsByTagName(r)[0]; if (ab) { var ag = ab.childNodes; if (ag) { var aa = ag.length; for (var ad = 0; ad < aa; ad++) { if (!(ag[ad].nodeType == 1 && ag[ad].nodeName == "PARAM") && !(ag[ad].nodeType == 8)) { ae.appendChild(ag[ad].cloneNode(true)) } } } } } return ae } function k(aa, ab) { var ac = C("div"); ac.innerHTML = "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'><param name='movie' value='" + aa + "'>" + ab + "</object>"; return ac.firstChild } function u(ai, ag, ab) { var aa, ad = c(ab); ab = W(ab); if (O.wk && O.wk < 312) { return aa } if (ad) { var ac = (O.ie) ? C("div") : C(r), af, ah, ae; if (typeof ai.id == D) { ai.id = ab } for (ae in ag) { if (ag.hasOwnProperty(ae) && ae.toLowerCase() !== "movie") { e(ac, ae, ag[ae]) } } if (O.ie) { ac = k(ai.data, ac.innerHTML) } for (af in ai) { if (ai.hasOwnProperty(af)) { ah = af.toLowerCase(); if (ah === "styleclass") { ac.setAttribute("class", ai[af]) } else { if (ah !== "classid" && ah !== "data") { ac.setAttribute(af, ai[af]) } } } } if (O.ie) { P[P.length] = ai.id } else { ac.setAttribute("type", q); ac.setAttribute("data", ai.data) } ad.parentNode.replaceChild(ac, ad); aa = ac } return aa } function e(ac, aa, ab) { var ad = C("param"); ad.setAttribute("name", aa); ad.setAttribute("value", ab); ac.appendChild(ad) } function y(ac) { var ab = c(ac); if (ab && ab.nodeName.toUpperCase() == "OBJECT") { if (O.ie) { ab.style.display = "none"; (function aa() { if (ab.readyState == 4) { for (var ad in ab) { if (typeof ab[ad] == "function") { ab[ad] = null } } ab.parentNode.removeChild(ab) } else { setTimeout(aa, 10) } }()) } else { ab.parentNode.removeChild(ab) } } } function U(aa) { return (aa && aa.nodeType && aa.nodeType === 1) } function W(aa) { return (U(aa)) ? aa.id : aa } function c(ac) { if (U(ac)) { return ac } var aa = null; try { aa = h.getElementById(ac) } catch (ab) { } return aa } function C(aa) { return h.createElement(aa) } function n(aa) { return parseInt(aa, 10) } function g(ac, aa, ab) { ac.attachEvent(aa, ab); K[K.length] = [ac, aa, ab] } function F(ac) { ac += ""; var ab = O.pv, aa = ac.split("."); aa[0] = n(aa[0]); aa[1] = n(aa[1]) || 0; aa[2] = n(aa[2]) || 0; return (ab[0] > aa[0] || (ab[0] == aa[0] && ab[1] > aa[1]) || (ab[0] == aa[0] && ab[1] == aa[1] && ab[2] >= aa[2])) ? true : false } function v(af, ab, ag, ae) { var ad = h.getElementsByTagName("head")[0]; if (!ad) { return } var aa = (typeof ag == "string") ? ag : "screen"; if (ae) { m = null; G = null } if (!m || G != aa) { var ac = C("style"); ac.setAttribute("type", "text/css"); ac.setAttribute("media", aa); m = ad.appendChild(ac); if (O.ie && typeof h.styleSheets != D && h.styleSheets.length > 0) { m = h.styleSheets[h.styleSheets.length - 1] } G = aa } if (m) { if (typeof m.addRule != D) { m.addRule(af, ab) } else { if (typeof h.createTextNode != D) { m.appendChild(h.createTextNode(af + " {" + ab + "}")) } } } } function w(ad, aa) { if (!j) { return } var ab = aa ? "visible" : "hidden", ac = c(ad); if (L && ac) { ac.style.visibility = ab } else { if (typeof ad === "string") { v("#" + ad, "visibility:" + ab) } } } function N(ab) { var ac = /[\\\"<>\.;]/; var aa = ac.exec(ab) != null; return aa && typeof encodeURIComponent != D ? encodeURIComponent(ab) : ab } var d = function () { if (O.ie) { window.attachEvent("onunload", function () { var af = K.length; for (var ae = 0; ae < af; ae++) { K[ae][0].detachEvent(K[ae][1], K[ae][2]) } var ac = P.length; for (var ad = 0; ad < ac; ad++) { y(P[ad]) } for (var ab in O) { O[ab] = null } O = null; for (var aa in swfobject) { swfobject[aa] = null } swfobject = null }) } }(); return {
        registerObject: function (ae, aa, ad, ac) { if (O.w3 && ae && aa) { var ab = {}; ab.id = ae; ab.swfVersion = aa; ab.expressInstall = ad; ab.callbackFn = ac; o[o.length] = ab; w(ae, false) } else { if (ac) { ac({ success: false, id: ae }) } } }, getObjectById: function (aa) { if (O.w3) { return z(aa) } }, embedSWF: function (af, al, ai, ak, ab, ae, ad, ah, aj, ag) { var ac = W(al), aa = { success: false, id: ac }; if (O.w3 && !(O.wk && O.wk < 312) && af && al && ai && ak && ab) { w(ac, false); M(function () { ai += ""; ak += ""; var an = {}; if (aj && typeof aj === r) { for (var aq in aj) { an[aq] = aj[aq] } } an.data = af; an.width = ai; an.height = ak; var ar = {}; if (ah && typeof ah === r) { for (var ao in ah) { ar[ao] = ah[ao] } } if (ad && typeof ad === r) { for (var am in ad) { if (ad.hasOwnProperty(am)) { var ap = (l) ? encodeURIComponent(am) : am, at = (l) ? encodeURIComponent(ad[am]) : ad[am]; if (typeof ar.flashvars != D) { ar.flashvars += "&" + ap + "=" + at } else { ar.flashvars = ap + "=" + at } } } } if (F(ab)) { var au = u(an, ar, al); if (an.id == ac) { w(ac, true) } aa.success = true; aa.ref = au; aa.id = au.id } else { if (ae && A()) { an.data = ae; R(an, ar, al, ag); return } else { w(ac, true) } } if (ag) { ag(aa) } }) } else { if (ag) { ag(aa) } } }, switchOffAutoHideShow: function () { j = false }, enableUriEncoding: function (aa) { l = (typeof aa === D) ? true : aa }, ua: O, getFlashPlayerVersion: function () { return { major: O.pv[0], minor: O.pv[1], release: O.pv[2] } }, hasFlashPlayerVersion: F, createSWF: function (ac, ab, aa) { if (O.w3) { return u(ac, ab, aa) } else { return undefined } }, showExpressInstall: function (ac, ad, aa, ab) { if (O.w3 && A()) { R(ac, ad, aa, ab) } }, removeSWF: function (aa) { if (O.w3) { y(aa) } }, createCSS: function (ad, ac, ab, aa) { if (O.w3) { v(ad, ac, ab, aa) } }, addDomLoadEvent: M, addLoadEvent: s, getQueryParamValue: function (ad) {
            var ac = h.location.search || h.location.hash;
            if (ac) { if (/\?/.test(ac)) { ac = ac.split("?")[1] } if (ad == null) { return N(ac) } var ab = ac.split("&"); for (var aa = 0; aa < ab.length; aa++) { if (ab[aa].substring(0, ab[aa].indexOf("=")) == ad) { return N(ab[aa].substring((ab[aa].indexOf("=") + 1))) } } } return ""
        }, expressInstallCallback: function () { if (a) { var aa = c(S); if (aa && I) { aa.parentNode.replaceChild(I, aa); if (p) { w(p, true); if (O.ie) { I.style.display = "block" } } if (E) { E(B) } } a = false } }, version: "2.3"
    }
}();
View Code
 function hasFlash() {
        return swfobject.hasFlashPlayerVersion("1");
    }

經過這方法判斷是最準確的。web

4.圖片顯示問題

1)在https的網站上出現http的請求,瀏覽器都會給出安全提醒,就ie喜歡彈出來。

這個也還好,微信在ie8中打開也會有這樣的提示,除非文件服務器也是https的,否則前端也是沒解。若是是在https中請求http的ajax,那直接掛掉。

2)IE8上在界面對大圖片設置max-width,會出現把父元素撐得很大而圖片顯示在一邊,留下一大塊空白。這個解決辦法就是給父類也加個max-width的樣式限制一下。

5.socket.io遇到https

這是這幾天一個嚴重的問題,到https上,ie8/9都收不到消息。我爲之很苦惱,由於socket都顯示鏈接成功了,也訂閱消息了,就是沒收到消息。這個socket.io號稱都支持到ie6的。各類搜索都沒有看到過相關問題。我有個經驗,若是一個問題,你搜了很都沒有找到相似的問題,可能有兩點,要麼這是個很傻的問題,哪一個地方設置下就行了,要麼就是個很偏很冷門的問題。可是明顯前者的可能性更大。

  socket = io('/', { 'transports': ['websocket', 'polling'] });
  socket.on("connect", function () {
  console.log('鏈接成功')                                    
  });

 //監聽頻道
 socket.on('messages', function (res) {
 console.log("收到消息",res);
 });

其實在http上的測試環境ie8是ok的,有一天晚上忽然調通了,我還高興的備份了代碼回家睡了個好覺,次日一來打開一看,懵逼了,仍是不行。難道是幻覺,昨天還在羣裏和隊友說好了,真是啪啪啪的打臉。而後再也沒經過了。其實socket.io的調用代碼很簡單,就那麼幾句。我再怎麼擺弄也沒啥用。最後仍是沒辦法,在ie8/9上面切到了傳統的輪詢。這個問題最後仍是沒有解決,同事說多是F5或者https的安全協議引發的。

 

6.不支持數組的indexof

若是是現代瀏覽器咱們能夠經過indexOf來判斷一個元素是否存在於數組

if (!~loadmesg.indexOf(json.MsgID))

但ie8不支持。得改爲for循環。

7.隱藏元素初始化上傳插件失敗

上傳的時候使用的是plupload插件,但若是目標元素是隱藏的,ie8上初始化會無效。

8.IE標準模式失效

咱們能夠用mate來指定ie8的渲染方式:

  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

但我發現不管我怎麼加,都是以ie7的方式打開的。而後就從新作了簡單的也沒,只有meta和文字,發現是有效果的,也就是說頁面上的某些緣由致使ie8又本身切換到了ie7的兼容模式

而後拿掉就能夠了。以前這麼寫是爲了添加一個過渡的樣式。沒想到形成了這種影響。只有再換一種方式實現。

9.jquery的一種寫法不支持

 var $a = $('<a target="_blank" class="' + c + '"     href=' + rightData[i].CustomerRightNavLink + '></a>');
            var img = '<img src=' + rightData[i].CustomerRightNavImage + ' />';
            $a.html(img);
            $(".hold").append($a);

引用的是jquery1.11.3 在ie8中會報錯。修改以下:

 var str = '<a target="_blank" class="' + c + '"     href=' + rightData[i].CustomerRightNavLink + '><img src=' + rightData[i].CustomerRightNavImage + ' /></a>'
            $(".hold").append(str);

小結:作兼容性也是爲了體驗性和穩定性,每個異常現象背後都是對一些基礎知識的考驗,之前作網站基本上都是一我的從頭作到位,跨域問題幾乎都沒遇到過,兼容性上也沒有死磕。如今正經作前端幾個月了,感受作兼容性是每一個前端的必備課,後端都知道現代瀏覽器方便好用,可是你寫代碼是爲了服務用戶的,不是方便本身,再者,作兼容性確實考驗各方面的知識,最好前端仍是要懂後端的以及網絡方面的知識。這樣遇到問題的時候不至於茫然無措,由於前端看到的現象已是異常的最後面目,你要分析找出最根本的緣由,而後找對應的同事幫忙解決。

相關文章
相關標籤/搜索