• 对各种异步回调都使用try catch错误上报


     
    var moon_init = function () {
        // 前端的@cunjinli
        (function () {
            // @cunjinli 重写alert函数, moonsafe监控
            var _alert = window.alert;
            window.__alertList = [];
            window.alert = function (msg) {
                _alert(msg);
                window.__alertList.push(msg);
            };
        })();
        /**
         * moonsafe @cunjinli 加在这里
         */
        (function () {
            // if (window.__nonce_str) {
            //   var __old_createElement = document.createElement;
            //   document.createElement = function(tagName) {
            //     var node = __old_createElement.apply(this, arguments);
            //     if (typeof tagName == 'object') {
            //       tagName = tagName.toString();
            //     }
            //     if (typeof tagName == 'string' && tagName.toLowerCase() == 'script') {
            //       node.setAttribute("nonce", window.__nonce_str);
            //     }
            //     return node;
            //   }
            // }
            if (window.addEventListener && window.__DEBUGINFO && Math.random() < 0.01) {
                window.addEventListener("load", function () {
                    var node = document.createElement('script');
                    node.src = __DEBUGINFO.safe_js;
                    node.type = 'text/javascript';
                    node.async = true;
                    var head = document.head || (document.getElementsByTagName("head")[0]);
                    head.appendChild(node);
                });
            }
        })();
        /**
         * mooncatch
         * 对各种异步回调都使用try catch错误上报
         * @radeonwu raphealguo
         */
        (function () {
            var inWx = (/MicroMessenger/i).test(navigator.userAgent);
            var inMp = (/MPAPP/i).test(navigator.userAgent);
            var _idkey = 121261; //上报的idkey 添加默认上报值
            var _startKey; //开始的key
            var _limit; //上报的key的长度
            var _badjsId;
            var _reportOpt; //上报的额外信息
            var _extInfo; //附加的预留字段,如网络采样率采样率network_rate, 总体上报率rate
            var MOON_LISTENER_ERROR_KEY_OFFSET = 2; //addEventListener上报时的偏移量为2
            var MOON_AJAX_NETWORK_OFFSET = 4; //network错误时的上报偏移量为4,这里在ajax.js中上报,这里需要加入采样率
            var MOON_ASYNC_ERROR_KEY_OFFSET = 9; //setTimeout和setInterval上报时的偏移量为9
            var MOON_LOCALSTORAGE_ERROR_KEY_OFFSET = 10; //localstorage.setItem失败时的偏移量为10
            window.__initCatch = function (opt) {
                _idkey = opt.idkey;
                _startKey = opt.startKey || 0;
                _limit = opt.limit;
                _badjsId = opt.badjsId;
                _reportOpt = opt.reportOpt || "";
                _extInfo = opt.extInfo || {};
                _extInfo.rate = _extInfo.rate || 0.5;
            }
            //暴露的上报函数,供core.js和ajax.js上报错误使用,array = [{offset:MOON_JSAPI_KEY_OFFSET, log:"ready", e:e}]
            window.__moon_report = function (array, rate_opt) {
                var isAcrossOrigin = false;
                var href = '';
                try {
                    href = top.location.href;
                } catch (e) {
                    isAcrossOrigin = true;
                }
                var rate = 0.5;
                if (!!_extInfo && !!_extInfo.rate) {
                    rate = _extInfo.rate;
                }
                if (!!rate_opt && (typeof rate_opt == 'number')) {
                    rate = rate_opt;
                }
                if (
                    (!(/mp\.weixin\.qq\.com/).test(location.href) && !(/payapp\.weixin\.qq\.com/).test(location.href)) ||
                    Math.random() > rate ||
                    !(inWx || inMp) ||
                    (top != window && !isAcrossOrigin && !(/mp\.weixin\.qq\.com/).test(href))
                ) {
                    //return ;
                }
                if (isObject(array))
                    array = [array];
                if (!isArray(array) || _idkey == '')
                    return;
                var data = "";
                var log = []; //存放array中每个对象关联的log
                var key = []; //存放array中每个上报的key
                var val = []; //存放array中每个上报的value
                var idkey = [];
                //如果这里没有opt.limit,直接上报到startKey
                if (typeof _limit != "number") {
                    _limit = Infinity;
                }
                for (var i = 0; i < array.length; i++) {
                    var item = array[i] || {};
                    if (item.offset > _limit) continue; //上报的偏移量超过limit
                    if (typeof item.offset != "number") continue;
                    if (item.offset == MOON_AJAX_NETWORK_OFFSET && !!_extInfo && !!_extInfo.network_rate && Math.random() >= _extInfo.network_rate) {
                        continue;
                    }
                    //log[i] = item.log || "";
                    var k = _limit == Infinity ? _startKey : (_startKey + item.offset);
                    log[i] = (("[moon]" + _idkey + "_" + k + ";") + item.log + ";" + getErrorMessage(item.e || {})) || "";
                    key[i] = k;
                    val[i] = 1;
                }
                for (var j = 0; j < key.length; j++) {
                    idkey[j] = _idkey + "_" + key[j] + "_" + val[j];
                    data = data + "&log" + j + "=" + log[j];
                }
                if (idkey.length > 0) {
                    // sendReport("idkey=" + idkey.join(";") + "&lc=" + log.length + data);
                    sendReport("POST", location.protocol + '//mp.weixin.qq.com/mp/jsmonitor?', "idkey=" + idkey.join(";") + "&r=" + Math.random() + "&lc=" + log.length + data);
                    // 把图文消息的错误上报一份到badjs,只支持get请求
                    // 这里由于量比较大,把badjs的内层怼爆了,这里加多一个采样,并且去掉用户的信息
                    var rate = 1;
                    if (_extInfo && _extInfo.badjs_rate) { // 初始化时的badjs采样率
                        rate = _extInfo.badjs_rate;
                    }
                    if (Math.random() < rate) {
                        data = data.replace(/uin\:(.)*\|biz\:(.)*\|mid\:(.)*\|idx\:(.)*\|sn\:(.)*\|/, '');
                        if (!!_badjsId) {
                            var _img = new Image();
                            var _src = 'https://badjs.weixinbridge.com/badjs?id=' + _badjsId + '&level=4&from=' + encodeURIComponent(location.host) + '&msg=' + encodeURIComponent(data);
                            _img.src = _src.slice(0, 1024);
                        }
                        // badjs同时报一份到新监控 
                        if (typeof WX_BJ_REPORT != "undefined" && WX_BJ_REPORT.BadJs) {
                            for (var i = 0; i < array.length; i++) {
                                var item = array[i] || {};
                                if (item.e) {
                                    WX_BJ_REPORT.BadJs.onError(item.e, { _info: item.log });
                                } else {
                                    var name = /[^:;]*/.exec(item.log)[0];
                                    WX_BJ_REPORT.BadJs.report(name, item.log, { mid: "mmbizwap:Monitor" });
                                }
                            }
                        }
                    } else {
                        //虽然采样没有执行 但实际是有被BadJs.onError,置位一下
                        for (var i = 0; i < array.length; i++) {
                            var item = array[i] || {};
                            if (item.e) {
                                item.e.BADJS_EXCUTED = true;
                            }
                        }
                    }
                }
            }
            function isArray(obj) { //判断输入是否为数组
                return Object.prototype.toString.call(obj) === '[object Array]';
            }
            function isObject(obj) { //判断输入是否为对象
                return Object.prototype.toString.call(obj) === '[object Object]';
            }
            function getErrorMessage(e) {
                var stack = e.stack + ' ' + e.toString() || ""; //错误堆栈信息
                try {
                    //先取出res域名
                    if (!window.testenv_reshost) {
                        stack = stack.replace(/http(s)?:\/\/res\.wx\.qq\.com/g, "");
                    } else {
                        var host = 'http(s)?://' + window.testenv_reshost;
                        var reg = new RegExp(host, 'g');
                        stack = stack.replace(reg, "");
                    }
                    //提取最后一个.js前边的
                    var reg = /\/([^.]+)\/js\/(\S+?)\.js(\,|:)?/g;
                    while (reg.test(stack)) {
                        // stack = stack.replace(reg, "3"); 解决$问题
                        stack = stack.replace(reg, function (a, b, c, d, e, f) {
                            return c + d
                        });
                    }
                } catch (e) {
                    stack = e.stack ? e.stack : "" //错误堆栈信息
                }
                var ret = [];
                for (o in _reportOpt) {
                    if (_reportOpt.hasOwnProperty(o)) {
                        ret.push(o + ":" + _reportOpt[o]);
                    }
                }
                ret.push("STK:" + stack.replace(/\n/g, ""));
                return ret.join("|");
            }
            function sendReport(type, url, data) { //post方法用于提交数据
                if (!/^mp\.weixin\.qq\.com$/.test(location.hostname)) { //非MP域名使用 img方式上报
                    var tmp = [];
                    data = data.replace(location.href, (location.origin || "") + (location.pathname || "")).replace("#wechat_redirect", "").replace("#rd", "").split("&");
                    for (var i = 0, il = data.length; i < il; i++) {
                        var a = data[i].split("=");
                        if (!!a[0] && !!a[1]) {
                            tmp.push(a[0] + "=" + encodeURIComponent(a[1]));
                        }
                    }
                    var _img = new window.Image();
                    _img.src = (url + tmp.join("&")).substr(0, 1024);
                    return;
                }
                var xmlobj; //定义XMLHttpRequest对象  
                if (window.ActiveXObject) { //如果当前浏览器支持Active Xobject,则创建ActiveXObject对象    
                    try {
                        xmlobj = new ActiveXObject("Msxml2.XMLHTTP");
                    } catch (e) {
                        try {
                            xmlobj = new ActiveXObject("Microsoft.XMLHTTP");
                        } catch (E) {
                            xmlobj = false;
                        }
                    }
                } else if (window.XMLHttpRequest) { //如果当前浏览器支持XMLHttpRequest,则创建XMLHttpRequest对象  
                    xmlobj = new XMLHttpRequest();
                }
                if (!xmlobj) return;
                //xmlobj.open("POST", location.protocol + "//mp.weixin.qq.com/mp/jsmonitor?", true);         
                xmlobj.open(type, url, true);
                xmlobj.setRequestHeader("cache-control", "no-cache");
                xmlobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //设置请求头信息              
                xmlobj.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                xmlobj.send(data); //发送数据  
            }
            function catTimeout(foo) {
                return function (cb, timeout) {
                    if (typeof cb === 'string') {
                        try {
                            cb = new Function(cb);
                        } catch (err) {
                            throw err;
                        }
                    }
                    var args = [].slice.call(arguments, 2);
                    var _cb = cb;
                    cb = function () {
                        try {
                            return _cb.apply(this, (args.length && args) || arguments);
                        } catch (error) {
                            if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                                console.error("[TryCatch]" + error.stack);
                            }
                            if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error
                                //sendReport(error);
                                window.__moon_report([{ offset: MOON_ASYNC_ERROR_KEY_OFFSET, log: "timeout_error;host:" + location.host, e: error }]);
                                //breakOnError(timeoutkey);
                            }
                            throw error;
                        }
                    }
                    return foo(cb, timeout);
                };
            };
            window.setTimeout = catTimeout(window.setTimeout);
            window.setInterval = catTimeout(window.setInterval);
            if (Math.random() < 0.01 && !!window.Document && !!window.HTMLElement) {
                var cb_map = {};
                var moon_lid = 0;
                function catAddListener(foo) {
                    return function (type, cb, useCapture) {
                        if (typeof useCapture === "undefined") {
                            var useCapture = false;
                        }
                        var that = this;
                        var _cb = cb || function () { };
                        cb = function () {
                            try {
                                //arguments[0].currentTarget.setAttribute("data-moon_lid") = moon_lid;
                                //_cb.moon_lid = moon_lid;
                                return _cb.apply(that, arguments);
                            } catch (error) {
                                if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                                    console.error("[TryCatch]" + error.stack);
                                }
                                if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error
                                    window.__moon_report([{ offset: MOON_LISTENER_ERROR_KEY_OFFSET, log: "listener_error;type:" + type + ";host:" + location.host, e: error }]);
                                    //breakOnError(timeoutkey);
                                }
                                throw error;
                            }
                        }
                        _cb.moon_lid = moon_lid;
                        cb_map[moon_lid] = cb;
                        moon_lid++;
                        return foo.call(that, type, cb, useCapture);
                    }
                }
                function catRemoveListener(foo) {
                    return function (type, cb, useCapture) {
                        if (typeof useCapture === "undefined") {
                            var useCapture = false;
                        }
                        var that = this;
                        cb = cb_map[cb.moon_lid];
                        return foo.call(that, type, cb, useCapture);
                    }
                }
                Document.prototype.addEventListener = catAddListener(Document.prototype.addEventListener);
                Document.prototype.removeEventListener = catRemoveListener(Document.prototype.removeEventListener);
                HTMLElement.prototype.addEventListener = catAddListener(HTMLElement.prototype.addEventListener);
                HTMLElement.prototype.removeEventListener = catRemoveListener(HTMLElement.prototype.removeEventListener);
            }
            //alert("setItem begin");
            //window.localStorage.setItem = function(){a=c;}//故意
            var ua = window.navigator.userAgent;
            if ((/ip(hone|ad|od)/i.test(ua) || /android/i.test(ua)) && !/windows phone/i.test(ua) && !!window.localStorage && !!window.localStorage.setItem) {
                var _setItem = window.localStorage.setItem;
                var count = 0;
                window.localStorage.setItem = function (k, v) {
                    if (count >= 10) { //一直失败 不要再继续试了,可能类似safari无痕模式 不允许写入了
                        return;
                    }
                    try {
                        _setItem.call(window.localStorage, k, v);
                    } catch (error) {
                        //alert(error);
                        if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                            console.error("[TryCatch]" + error.stack);
                        }
                        window.__moon_report([{ offset: MOON_LOCALSTORAGE_ERROR_KEY_OFFSET, log: "localstorage_error;" + error.toString(), e: error }]);
                        count++;
                        if (count >= 3 && !!window.moon && window.moon.clear) {
                            // 可能爆满 清理一下localstorage
                            moon.clear();
                        }
                    }
                }
                //alert("setItem end");
            }
        })();
        // 后面的@cunjinli
    };
    moon_init();
      //由于moon异步化,所以有些逻辑需要moon加载完之后才执行的 放到全局callback函数__moon_initcallback里边
    

      view-source:https://mp.weixin.qq.com/s/_xsb_91-eQAq10IyDa2tvQ

    var moon_init = function () {
        // 前端的@cunjinli
        (function () {
            // @cunjinli 重写alert函数, moonsafe监控
            var _alert = window.alert;
            window.__alertList = [];
            window.alert = function (msg) {
                _alert(msg);
                window.__alertList.push(msg);
            };
        })();
        /**
         * moonsafe @cunjinli 加在这里
         */
        (function () {
            // if (window.__nonce_str) {
            //   var __old_createElement = document.createElement;
            //   document.createElement = function(tagName) {
            //     var node = __old_createElement.apply(this, arguments);
            //     if (typeof tagName == 'object') {
            //       tagName = tagName.toString();
            //     }
            //     if (typeof tagName == 'string' && tagName.toLowerCase() == 'script') {
            //       node.setAttribute("nonce", window.__nonce_str);
            //     }
            //     return node;
            //   }
            // }
            if (window.addEventListener && window.__DEBUGINFO && Math.random() < 0.01) {
                window.addEventListener("load", function () {
                    var node = document.createElement('script');
                    node.src = __DEBUGINFO.safe_js;
                    node.type = 'text/javascript';
                    node.async = true;
                    var head = document.head || (document.getElementsByTagName("head")[0]);
                    head.appendChild(node);
                });
            }
        })();
        /**
         * mooncatch
         * 对各种异步回调都使用try catch错误上报
         * @radeonwu raphealguo
         */
        (function () {
            var inWx = (/MicroMessenger/i).test(navigator.userAgent);
            var inMp = (/MPAPP/i).test(navigator.userAgent);
            var _idkey = 121261; //上报的idkey 添加默认上报值
            var _startKey; //开始的key
            var _limit; //上报的key的长度
            var _badjsId;
            var _reportOpt; //上报的额外信息
            var _extInfo; //附加的预留字段,如网络采样率采样率network_rate, 总体上报率rate
            var MOON_LISTENER_ERROR_KEY_OFFSET = 2; //addEventListener上报时的偏移量为2
            var MOON_AJAX_NETWORK_OFFSET = 4; //network错误时的上报偏移量为4,这里在ajax.js中上报,这里需要加入采样率
            var MOON_ASYNC_ERROR_KEY_OFFSET = 9; //setTimeout和setInterval上报时的偏移量为9
            var MOON_LOCALSTORAGE_ERROR_KEY_OFFSET = 10; //localstorage.setItem失败时的偏移量为10
            window.__initCatch = function (opt) {
                _idkey = opt.idkey;
                _startKey = opt.startKey || 0;
                _limit = opt.limit;
                _badjsId = opt.badjsId;
                _reportOpt = opt.reportOpt || "";
                _extInfo = opt.extInfo || {};
                _extInfo.rate = _extInfo.rate || 0.5;
            }
            //暴露的上报函数,供core.js和ajax.js上报错误使用,array = [{offset:MOON_JSAPI_KEY_OFFSET, log:"ready", e:e}]
            window.__moon_report = function (array, rate_opt) {
                var isAcrossOrigin = false;
                var href = '';
                try {
                    href = top.location.href;
                } catch (e) {
                    isAcrossOrigin = true;
                }
                var rate = 0.5;
                if (!!_extInfo && !!_extInfo.rate) {
                    rate = _extInfo.rate;
                }
                if (!!rate_opt && (typeof rate_opt == 'number')) {
                    rate = rate_opt;
                }
                if (
                    (!(/mp\.weixin\.qq\.com/).test(location.href) && !(/payapp\.weixin\.qq\.com/).test(location.href)) ||
                    Math.random() > rate ||
                    !(inWx || inMp) ||
                    (top != window && !isAcrossOrigin && !(/mp\.weixin\.qq\.com/).test(href))
                ) {
                    //return ;
                }
                if (isObject(array))
                    array = [array];
                if (!isArray(array) || _idkey == '')
                    return;
                var data = "";
                var log = []; //存放array中每个对象关联的log
                var key = []; //存放array中每个上报的key
                var val = []; //存放array中每个上报的value
                var idkey = [];
                //如果这里没有opt.limit,直接上报到startKey
                if (typeof _limit != "number") {
                    _limit = Infinity;
                }
                for (var i = 0; i < array.length; i++) {
                    var item = array[i] || {};
                    if (item.offset > _limit) continue; //上报的偏移量超过limit
                    if (typeof item.offset != "number") continue;
                    if (item.offset == MOON_AJAX_NETWORK_OFFSET && !!_extInfo && !!_extInfo.network_rate && Math.random() >= _extInfo.network_rate) {
                        continue;
                    }
                    //log[i] = item.log || "";
                    var k = _limit == Infinity ? _startKey : (_startKey + item.offset);
                    log[i] = (("[moon]" + _idkey + "_" + k + ";") + item.log + ";" + getErrorMessage(item.e || {})) || "";
                    key[i] = k;
                    val[i] = 1;
                }
                for (var j = 0; j < key.length; j++) {
                    idkey[j] = _idkey + "_" + key[j] + "_" + val[j];
                    data = data + "&log" + j + "=" + log[j];
                }
                if (idkey.length > 0) {
                    // sendReport("idkey=" + idkey.join(";") + "&lc=" + log.length + data);
                    sendReport("POST", location.protocol + '//mp.weixin.qq.com/mp/jsmonitor?', "idkey=" + idkey.join(";") + "&r=" + Math.random() + "&lc=" + log.length + data);
                    // 把图文消息的错误上报一份到badjs,只支持get请求
                    // 这里由于量比较大,把badjs的内层怼爆了,这里加多一个采样,并且去掉用户的信息
                    var rate = 1;
                    if (_extInfo && _extInfo.badjs_rate) { // 初始化时的badjs采样率
                        rate = _extInfo.badjs_rate;
                    }
                    if (Math.random() < rate) {
                        data = data.replace(/uin\:(.)*\|biz\:(.)*\|mid\:(.)*\|idx\:(.)*\|sn\:(.)*\|/, '');
                        if (!!_badjsId) {
                            var _img = new Image();
                            var _src = 'https://badjs.weixinbridge.com/badjs?id=' + _badjsId + '&level=4&from=' + encodeURIComponent(location.host) + '&msg=' + encodeURIComponent(data);
                            _img.src = _src.slice(0, 1024);
                        }
                        // badjs同时报一份到新监控
                        if (typeof WX_BJ_REPORT != "undefined" && WX_BJ_REPORT.BadJs) {
                            for (var i = 0; i < array.length; i++) {
                                var item = array[i] || {};
                                if (item.e) {
                                    WX_BJ_REPORT.BadJs.onError(item.e, { _info: item.log });
                                } else {
                                    var name = /[^:;]*/.exec(item.log)[0];
                                    WX_BJ_REPORT.BadJs.report(name, item.log, { mid: "mmbizwap:Monitor" });
                                }
                            }
                        }
                    } else {
                        //虽然采样没有执行 但实际是有被BadJs.onError,置位一下
                        for (var i = 0; i < array.length; i++) {
                            var item = array[i] || {};
                            if (item.e) {
                                item.e.BADJS_EXCUTED = true;
                            }
                        }
                    }
                }
            }
            function isArray(obj) { //判断输入是否为数组
                return Object.prototype.toString.call(obj) === '[object Array]';
            }
            function isObject(obj) { //判断输入是否为对象
                return Object.prototype.toString.call(obj) === '[object Object]';
            }
            function getErrorMessage(e) {
                var stack = e.stack + ' ' + e.toString() || ""; //错误堆栈信息
                try {
                    //先取出res域名
                    if (!window.testenv_reshost) {
                        stack = stack.replace(/http(s)?:\/\/res\.wx\.qq\.com/g, "");
                    } else {
                        var host = 'http(s)?://' + window.testenv_reshost;
                        var reg = new RegExp(host, 'g');
                        stack = stack.replace(reg, "");
                    }
                    //提取最后一个.js前边的
                    var reg = /\/([^.]+)\/js\/(\S+?)\.js(\,|:)?/g;
                    while (reg.test(stack)) {
                        // stack = stack.replace(reg, "3"); 解决$问题
                        stack = stack.replace(reg, function (a, b, c, d, e, f) {
                            return c + d
                        });
                    }
                } catch (e) {
                    stack = e.stack ? e.stack : "" //错误堆栈信息
                }
                var ret = [];
                for (o in _reportOpt) {
                    if (_reportOpt.hasOwnProperty(o)) {
                        ret.push(o + ":" + _reportOpt[o]);
                    }
                }
                ret.push("STK:" + stack.replace(/\n/g, ""));
                return ret.join("|");
            }
            function sendReport(type, url, data) { //post方法用于提交数据
                if (!/^mp\.weixin\.qq\.com$/.test(location.hostname)) { //非MP域名使用 img方式上报
                    var tmp = [];
                    data = data.replace(location.href, (location.origin || "") + (location.pathname || "")).replace("#wechat_redirect", "").replace("#rd", "").split("&");
                    for (var i = 0, il = data.length; i < il; i++) {
                        var a = data[i].split("=");
                        if (!!a[0] && !!a[1]) {
                            tmp.push(a[0] + "=" + encodeURIComponent(a[1]));
                        }
                    }
                    var _img = new window.Image();
                    _img.src = (url + tmp.join("&")).substr(0, 1024);
                    return;
                }
                var xmlobj; //定义XMLHttpRequest对象  
                if (window.ActiveXObject) { //如果当前浏览器支持Active Xobject,则创建ActiveXObject对象    
                    try {
                        xmlobj = new ActiveXObject("Msxml2.XMLHTTP");
                    } catch (e) {
                        try {
                            xmlobj = new ActiveXObject("Microsoft.XMLHTTP");
                        } catch (E) {
                            xmlobj = false;
                        }
                    }
                } else if (window.XMLHttpRequest) { //如果当前浏览器支持XMLHttpRequest,则创建XMLHttpRequest对象  
                    xmlobj = new XMLHttpRequest();
                }
                if (!xmlobj) return;
                //xmlobj.open("POST", location.protocol + "//mp.weixin.qq.com/mp/jsmonitor?", true);        
                xmlobj.open(type, url, true);
                xmlobj.setRequestHeader("cache-control", "no-cache");
                xmlobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //设置请求头信息              
                xmlobj.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                xmlobj.send(data); //发送数据  
            }
            function catTimeout(foo) {
                return function (cb, timeout) {
                    if (typeof cb === 'string') {
                        try {
                            cb = new Function(cb);
                        } catch (err) {
                            throw err;
                        }
                    }
                    var args = [].slice.call(arguments, 2);
                    var _cb = cb;
                    cb = function () {
                        try {
                            return _cb.apply(this, (args.length && args) || arguments);
                        } catch (error) {
                            if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                                console.error("[TryCatch]" + error.stack);
                            }
                            if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error
                                //sendReport(error);
                                window.__moon_report([{ offset: MOON_ASYNC_ERROR_KEY_OFFSET, log: "timeout_error;host:" + location.host, e: error }]);
                                //breakOnError(timeoutkey);
                            }
                            throw error;
                        }
                    }
                    return foo(cb, timeout);
                };
            };
            window.setTimeout = catTimeout(window.setTimeout);
            window.setInterval = catTimeout(window.setInterval);
            if (Math.random() < 0.01 && !!window.Document && !!window.HTMLElement) {
                var cb_map = {};
                var moon_lid = 0;
                function catAddListener(foo) {
                    return function (type, cb, useCapture) {
                        if (typeof useCapture === "undefined") {
                            var useCapture = false;
                        }
                        var that = this;
                        var _cb = cb || function () { };
                        cb = function () {
                            try {
                                //arguments[0].currentTarget.setAttribute("data-moon_lid") = moon_lid;
                                //_cb.moon_lid = moon_lid;
                                return _cb.apply(that, arguments);
                            } catch (error) {
                                if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                                    console.error("[TryCatch]" + error.stack);
                                }
                                if (!!_idkey && !!window.__moon_report) { //没有初始化_key,直接throw error
                                    window.__moon_report([{ offset: MOON_LISTENER_ERROR_KEY_OFFSET, log: "listener_error;type:" + type + ";host:" + location.host, e: error }]);
                                    //breakOnError(timeoutkey);
                                }
                                throw error;
                            }
                        }
                        _cb.moon_lid = moon_lid;
                        cb_map[moon_lid] = cb;
                        moon_lid++;
                        return foo.call(that, type, cb, useCapture);
                    }
                }
                function catRemoveListener(foo) {
                    return function (type, cb, useCapture) {
                        if (typeof useCapture === "undefined") {
                            var useCapture = false;
                        }
                        var that = this;
                        cb = cb_map[cb.moon_lid];
                        return foo.call(that, type, cb, useCapture);
                    }
                }
                Document.prototype.addEventListener = catAddListener(Document.prototype.addEventListener);
                Document.prototype.removeEventListener = catRemoveListener(Document.prototype.removeEventListener);
                HTMLElement.prototype.addEventListener = catAddListener(HTMLElement.prototype.addEventListener);
                HTMLElement.prototype.removeEventListener = catRemoveListener(HTMLElement.prototype.removeEventListener);
            }
            //alert("setItem begin");
            //window.localStorage.setItem = function(){a=c;}//故意
            var ua = window.navigator.userAgent;
            if ((/ip(hone|ad|od)/i.test(ua) || /android/i.test(ua)) && !/windows phone/i.test(ua) && !!window.localStorage && !!window.localStorage.setItem) {
                var _setItem = window.localStorage.setItem;
                var count = 0;
                window.localStorage.setItem = function (k, v) {
                    if (count >= 10) { //一直失败 不要再继续试了,可能类似safari无痕模式 不允许写入了
                        return;
                    }
                    try {
                        _setItem.call(window.localStorage, k, v);
                    } catch (error) {
                        //alert(error);
                        if (error.stack && console && console.error) { //chrome有bug,特定情况下看不到throw的error,这里console.error下,防止给调试留坑
                            console.error("[TryCatch]" + error.stack);
                        }
                        window.__moon_report([{ offset: MOON_LOCALSTORAGE_ERROR_KEY_OFFSET, log: "localstorage_error;" + error.toString(), e: error }]);
                        count++;
                        if (count >= 3 && !!window.moon && window.moon.clear) {
                            // 可能爆满 清理一下localstorage
                            moon.clear();
                        }
                    }
                }
                //alert("setItem end");
            }
        })();
        // 后面的@cunjinli
    };
    moon_init();
      //由于moon异步化,所以有些逻辑需要moon加载完之后才执行的 放到全局callback函数__moon_initcallback里边
  • 相关阅读:
    记一个微信公众号个性化菜单的坑
    初学c# -- 学习笔记(六) winfrom组件圆角
    Swift中添加标记(MARK)和警告(TODO FIXME)
    iOS Xib布局某些控件显示或隐藏<约束的修改>
    [!] Unable to satisfy the following requirements:
    React Native使用NetInfo对当前系统网络的判断
    iOS自定义下拉列表
    [!] The version of CocoaPods used to generate the lockfile (1.4.0.beta.1) is higher than the version of the current executable (1.3.0.beta.1). Incompatibility issues may arise.
    iOS实现TextField光标居中
    iOS优秀第三方框架
  • 原文地址:https://www.cnblogs.com/rsapaper/p/16355447.html
Copyright © 2020-2023  润新知