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。。。。问题总是一步步解决的。。

    匿了~

  • 相关阅读:
    Frequency of String CodeForces
    Sign on Fence CodeForces
    洛谷 P3332 [ZJOI2013]K大数查询 || bzoj3110
    spoj DYNALCA
    洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)
    洛谷 P3203 [HNOI2010]弹飞绵羊 || bzoj2002
    bzoj 1036: [ZJOI2008]树的统计Count
    Shiro Authenticator认证器
    Shiro 十分钟教程
    Shiro 架构
  • 原文地址:https://www.cnblogs.com/cyITtech/p/3738418.html
Copyright © 2011-2022 走看看