JavaScript異常監視

4413 ワード

JavaScript異常は、一般的にtry catchで捕獲されますが、try catchでは遅延実行されたコードは捕獲できません.この時はwindow.onerrorでしか捕獲できません.エラー情報を取得します.同時に、リンクを記録するなど、エラー情報を一括処理する必要があります.リンクのエラーを統計します.
        try catchとwindow.onerrorの異常捕獲はもう別の文章で基本的に説明されました.ここで異常情報の捕獲の詳細を説明します.
        開発者は比較的に注目しています.(1)現在はどのブラウザですか?(2)エラー情報;(3)スタックを呼び出します
ブラウザ情報の取得
        ブラウザ情報はnavigator.userAgentに格納されています.

var ua = navigator.userAgent.toLowerCase(), 
      bom = window.ActiveXObject ? "IE" + ua.match(/msie ([d.]+)/)[1] 
           : document.getBoxObjectFor ? "Firefox" + ua.match(/firefox/([d.]+)/)[1]
           : (ua.indexOf("chrome") != -1) ? "Chrome" + ua.match(/chrome/([d.]+)/)[1]
           : window.opera ? "Opera" + ua.match(/opera.([d.]+)/)[1]
           : window.openDatabase ? "Safari" + ua.match(/version/([d.]+)/)[1] : ua.replace(/s*/g, "");
        正規表現は、みんなが知っています.マッチングは各ブラウザのブラウザ名とブラウザバージョン番号です.
エラーメッセージ
情報フォーマット:ブラウザとバージョン番号リンク:スタックエラー情報
コールスタック
        イベントにスタック情報が含まれているなら、e.stackから情報を取得するという考え方です.さもないと、パラメータのargmentsがcalee上位を含む場合、巡回callオブジェクトは、スタックを呼び出して取得されます.空に戻るしかないです.

(function() {
    function $getStack(e, d) {
        if (e && e.stack) {
            var s = e.stack.replace(/(?:http:)[^:]*:(.*)/g, "$1").replace(
                    /[ns]/g, "").replace(/@/g, "at").split("at"), l = d ? d + 1
                    : s.length - 1;
            return s.slice(1, l).join(":");
        } else if (arguments.callee.caller.caller) {
            var curr = arguments.callee.caller.caller, c, o = [];
            while (curr) {
                c = curr;
                o.push(c.toString().replace(/function/g, "Fn").replace(
                        /[tnr]/g, "").substring(0, 30));
                curr = curr.caller;
            }
            return o.join(":");
        } else {
            return "";
        }
    };
    function $initBadjs() {
        var errorStr = "";
        window.onerror = function(msg, url, l) {
            var stack = $getStack(), ts = msg.replace(/n/g, " ") + "|"
                    + encodeURIComponent(url + ":" + stack) + "|" + l;
            if (errorStr.indexOf(ts) == -1) {
                errorStr += ts + ",";
                $sendBadjs(msg, url, l + ":" + stack);
            }
            return false;
        };
    }
    ;
    function $sendBadjs(msg, src, d) {
        var ua = navigator.userAgent.toLowerCase(), 
            bom = window.ActiveXObject ? "IE" + ua.match(/msie ([d.]+)/)[1]
                : document.getBoxObjectFor ? "Firefox" + ua.match(/firefox/([d.]+)/)[1]
                : (ua.indexOf("chrome") != -1) ? "Chrome" + ua.match(/chrome/([d.]+)/)[1]
                : window.opera ? "Opera" + ua.match(/opera.([d.]+)/)[1]
                : window.openDatabase ? "Safari" + ua.match(/version/([d.]+)/)[1] : ua.replace(/s*/g, ""),
            ts = msg.replace(/n/g, " ") + "|" + encodeURIComponent(src) + "|" + d;
        setTimeout(function() {
            sr = document.createElement("script");
            document.getElementsByTagName("head")[0].appendChild(sr);
                        //                
            sr.src = "http://42.96.169.98/projdemo/TestError?Browser=" + bom
                    + "&Url=" + encodeURIComponent(location.href) + "&Content="
                    + ts + "&t=" + Math.random();
        }, 1000);
    }
    ;
    $initBadjs();
    window._sendBadjs = $sendBadjs;
})();
参照
w 3 c onerror:http://www.w3.org/TR/2010/WD-html5-20100624/webappapis.html#handler-window-onerror
msdn onerror:http://msdn.microsoft.com/en-us/library/cc197053%28VS.85%29.aspx
firefox chrome onerror:http://stackoverflow.com/questions/5913978/cryptic-script-error-reported-in-javascript-in-chrome-and-firefox