zoukankan      html  css  js  c++  java
  • js bug自动预警

    这两天在看关于AMD中getCurrentScript函数时,突然想到,既然可以检测出当前出错的js文件,那么是不是可以做一个自动js bug预警的功能。以后只要有js错误出现,就会自动将错误上传到服务器。

    先看司徒正美大大书中写的一段关于检测js文件地址的函数,相关博客地址点这

    function getCurrentScript(base) {
            // 参考 https://github.com/samyk/jiagra/blob/master/jiagra.js
            var stack;
            try {
                a.b.c(); //强制报错,以便捕获e.stack
            } catch (e) { //safari的错误对象只有line,sourceId,sourceURL
                stack = e.stack;
                if (!stack && window.opera) {
                    //opera 9没有e.stack,但有e.Backtrace,但不能直接取得,需要对e对象转字符串进行抽取
                    stack = (String(e).match(/of linked script S+/g) || []).join(" ");
                }
            }
            if (stack) {
                /**e.stack最后一行在所有支持的浏览器大致如下:
                 *chrome23:
                 * at http://113.93.50.63/data.js:4:1
                 *firefox17:
                 *@http://113.93.50.63/query.js:4
                 *opera12:http://www.oldapps.com/opera.php?system=Windows_XP
                 *@http://113.93.50.63/data.js:4
                 *IE10:
                 *  at Global code (http://113.93.50.63/data.js:4:1)
                 *  //firefox4+ 可以用document.currentScript
                 */
                stack = stack.split(/[@ ]/g).pop(); //取得最后一行,最后一个空格或@之后的部分
                stack = stack[0] === "(" ? stack.slice(1, -1) : stack.replace(/s/, ""); //去掉换行符
                return stack.replace(/(:d+)?:d+$/i, ""); //去掉行号与或许存在的出错字符起始位置
            }
            var nodes = (base ? document : head).getElementsByTagName("script"); //只在head标签中寻找
            for (var i = nodes.length, node; node = nodes[--i]; ) {
                if ((base || node.className === moduleClass) && node.readyState === "interactive") {
                    return node.className = node.src;
                }
            }
        }

    后面的node操纵是为了兼容IE,我们先不要管坑爹的IE,先来看看让我们心情愉悦的现代浏览器

    在上面的函数,可以发现,e.stack简直是大杀器,基本只要分析里面的内容,就可以拿到具体错误位置

    但是这段函数执行是有条件的,我们必须让其在加载进来的js文件环境下执行,这样才会报那个文件的错误嘛

    为了模拟这个环境,我就顺手抄了个AMD,CMD中都用的函数define~

    function define(callback){
        try{
            callback();
        }catch(e){
            var stack;
            stack = e.stack;
            if(!stack && window.opera){
                stack = (String(e).match(/of linked script S+/g) || []).join(" ");
            }
            if(stack){
                stack = stack.split(/[@ ]/g).pop();
                stack = stack[0] === '(' ? stack.slice(1,-1):stack.replace(/s/,"");
                stack = stack.replace(/(:d+)?:d*$/i,'');
                bug_upload(stack);
                return;
            }
        }
    }

    里面的bug_upload是用来处理拿到的错误路径用的,这里为了方便,里面只是仅仅把路径alert出来。

    然后我们把加载尽量的js用define包上,然后在测试代码里随便加了一个错误:

    define(function(){
        function test_bug(){
            a.b.c();
        }
    
        test_bug();
    });

    准确弹出错误地址:

    哇,好赞!那么下面我们就要搞定IE

    IE新版本里面已经支持e.stack了,我们先干了IE旧版本!

    考虑到IE发生错误时老弹出一个框,说你的页面有错误,很是让人愤怒!于是我觉得给他绑一个onerror事件:

    window.onerror = function(msg,url){
        bug_upload(url);
        return true;
    }

    怎么把这段东西放到原来检测的大函数中呢,嘿嘿:

    function define(callback){
        try{
            callback()
        }catch(e){
            var stack;
            stack = e.stack;
            if(!stack && window.opera){
                stack = (String(e).match(/of linked script S+/g) || []).join(" ");
            }
            if(stack){
                stack = stack.split(/[@ ]/g).pop();
                stack = stack[0] === '(' ? stack.slice(1,-1):stack.replace(/s/,"");
                stack = stack.replace(/(:d+)?:d*$/i,'');
                bug_upload(stack);
                return;
            }
            window.onerror = function(msg,url){
                bug_upload(url);
                return true;
            }
            window.fireEvent && window.fireEvent('onerror',e);
        }
    }
    function bug_upload(path){
        alert(path);
    }

    搞定!!虽然这里IE老版本下只会弹出当前出错的html。。。。问题总是一步步解决的。。

    匿了~

  • 相关阅读:
    Linux——shell简单学习(一)
    Linux——进程管理简单学习笔记(二)
    Linux——进程管理学习简单笔记
    Linux——用户管理简单学习笔记(四)
    PHP计算程序运行时间的类
    php几个常用的概率算法(抽奖、广告首选)
    限制非安全IP访问
    简单的点击短信发送计时器
    php 以图搜图
    递归获取二维数组后代、删除后代
  • 原文地址:https://www.cnblogs.com/cyITtech/p/3738418.html
Copyright © 2011-2022 走看看