web前端错误监控

更新日期: 2019-06-26 阅读: 3.2k 标签: 错误

为什么要做前端错误监控?

1. 为了保证产品的质量

2. 有些问题只存在于线上特定的环境

3. 后端错误有监控,前端错误没有监控


前端错误的分类

前端错误分为两类: 即时运行错误和资源加载错误


即使运行错误的捕获方式

即时运行错误的捕获方式分为两类

  1. try...catch
  2. window.onerror

try...catch

通过try...catch我们能够知道出错的信息,并且也有堆栈信息可以知道在哪个文件第几行第几列发生错误

try {
           // 代码段
} catch (err) {
     console.log(err.message)
 }

缺点:

  1. 没法捕捉try,catch块,当前代码块有语法错误,JS解释器压根都不会执行当前这个代码块,所以也就没办法被catch住;
  2. 没法捕捉到全局的错误事件,也即是只有try,catch的块里边运行出错才会被你捕捉到,这里的块你要理解成一个函数

关于第一个缺点,我们没有任何解决办法,但是一般语法阶段我们是能在开发阶段/或者用工具检测到的,于是乎它就被忽略了

第二个缺点应该怎么理解呢? try...catch只能捕捉到当前执行流里边的运行错误,对于异步回调来说,是不属于这个try...catch块的


window.onerror

全局捕获。window.onerror一样可以拿到出错的信息以及文件名、行号、列号等信息,还可以在window.onerror最后return true让浏览器不输出错误信息到控制台

/*
         * @param msg{String}:错误消息
         * @param url{String}:引发错误的脚本的URL
         * @param line{Number}:发生错误的代码行
         * @param colunm{Number}:发生错误的代码列
         * @param error{object}:错误对象
         */

        window.onerror = function (msg, url, line, colunm, error) {
            // 返回 true 则错误消息不显示在控制台,返回 false,则错误消息将会展示在控制台
            return true;
        }

最后window.onerror的实现方法

window.onerror = function (msg, url, line, col, error) {
            //没有URL不上报!上报也不知道错误
            if (msg != "Script error." && !url) {
                return true;
            }
            
            setTimeout(function () {
                var data = {};
                //不一定所有浏览器都支持col参数
                col = col || (window.event && window.event.errorCharacter) || 0;

                data.url = url;
                data.line = line;
                data.col = col;
                if (!!error && !!error.stack) {
                    //如果浏览器有堆栈信息
                    //直接使用
                    data.msg = error.stack.toString();
                } else if (!!arguments.callee) {
                    //尝试通过callee拿堆栈信息
                    var ext = [];
                    var f = arguments.callee.caller,
                        c = 3;
                    //这里只拿三层堆栈信息
                    while (f && (--c > 0)) {
                        ext.push(f.toString());
                        if (f === f.caller) {
                            break; //如果有环
                        }
                        f = f.caller;
                    }
                    ext = ext.join(",");
                    data.msg = ext;
                }
                //把data上报到后台!
                console.log(data)
            }, 0);
            
            return true;
        };

资源加载错误

object.onerror

img、script标签都可以添加onerror事件,当资源请求失败的时候,都会触发该事件

 var img = document.getElementById('img');
img.onerror=function(){
    console.log("出错啦");
}

 

performance.getEntries()

performance是h5的新特性之一,使用该方法能获取到当前页面已经加载到的资源,返回的是一个数组对象。下面给出一个例子

获取页面中没有成功加载的图片资源?

步骤一:通过performance.getEntries()获取已经加载了的图片资源

let arr = [],
            reg = (/\.jpg$|\.jpeg$|.png$|\.gif$/i);
        performance.getEntries().forEach(item => {
            if (reg.test(item.name)) {
               arr.push(item.name)
            }
        })

步骤二:获取页面中所有的img标签

let imgList=document.getElementByTagname('img')

步骤三:利用获取到的img的长度减去已经加载到的长度,如果大于0的部分,就是加载失败的

let arr = [],
        imgList=null,
        num=0,
            reg = (/\.jpg$|\.jpeg$|.png$|\.gif$/i);
        performance.getEntries().forEach(item => {
            if (reg.test(item.name)) {
               arr.push(item.name)
            }
        })
        imgList=document.getElementsByTagName('img');
        num=imgList.length-arr.length;

Error事件捕获

资源加载错误,虽然会阻止冒泡,但是不会阻止捕获。true:捕获,false:冒泡

// window.addEventListener第三个参数是true的时候是捕获的过程,false是冒泡的过程 
window.addEventListener('error',function(e){
        console.log("捕获",e)
    },true)

 

跨域的JS文件异常捕获

为了提升web性能,大部分web产品都有CDN部署,将资源部署到不同的域名上,但是我们都知道浏览器是有同源策略的,当加载不同域名的脚本发生错误时,语法错误的细节不会报告,仅返回"Script error",针对这种问题,可以在服务器上设置"Access-Control-Allow-Origin:*",在请求资源的script标签上加上crossorigin属性即可

 <script src="xxxx/js/store.js" crossorigin></script>

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/3907

相关推荐

解决Cannot read property range of null 错误

vue工程npm run serve/start/dev启动时,node_modules文件报:Cannot read property range of null 错误,该问题是babel-eslint版本更新问题导致的;

开始使用Vue 3时应避免的10个错误

Vue 3 稳定已经有一段时间了。许多代码库正在生产中使用它,其他人最终也必须进行迁移。我有机会与它一起工作,并记录了我的错误,这可能是你想避免的。

HTTP 400 错误 - 请求无效 (Bad request)

在ajax请求后台数据时有时会报 HTTP 400 错误 - 请求无效 (Bad request);出现这个请求无效报错说明请求没有进入到后台服务里;原因:前端提交数据的字段名称或者是字段类型和后台的实体类不一致

nodejs提示 cross-device link not permitted, rename 错误解决方法

文件上传的功能时候,调用fs.renameSync方法错误,这个提示是跨区重命名文件出现的权限问题。先从源文件拷贝到另外分区的目标文件,然后再unlink,就可以了。

Js中使用innerHTML的缺点是什么?

如果在JavaScript中使用innerHTML,缺点是:内容随处可见;不能像“追加到innerHTML”一样使用;innerHTML不提供验证,因此我们可能会在文档中插入有效的和破坏性的HTML并将其中断

javascript如何抛出错误?

throw语句用来抛出一个用户自定义的异常。当前函数的执行将被停止(throw之后的语句将不会执行),并且控制将被传递到调用堆栈中的第一个catch块。如果调用者函数中没有catch块,程序将会终止。

解决typescript Cannot redeclare block-scoped variable

没有依赖框架来写typescript,纯粹新建一个ts文件,使用tsc编译成js后,ts文件里的声明的变量、函数名都会报错:其实我们写的ts代码是没有问题的,只是ts会对我们声明的变量、具名函数、class都放在了全局作用域

不能执行已释放Script的代码

父页面初始化声明变量a为数组(数组对象是引用类型,赋值传递的是地址),创建iframe子页面后给父页面变量a赋值,赋值后销毁iframe子页面,再次调用变量a的时候就会抛出异常‘SCRIPT5011:不能执行已释放Script的代码’。

避免那些可恶的cannot read property of undefined 错误

Uncaught TypeError: Cannot read property foo of undefined. 是一个我们在 JavaScript 开发中都遇到过的可怕错误。或许是某个 API 返回了意料外的空值,又或许是其它什么原因,这个错误是如此的普遍而广泛以至于我们无法判断

自定义错误及扩展错误

当我们在进行开发的时候,通常需要属于我们自己的错误类来反映任务中可能出现的特殊情况。对于网络操作错误,我们需要 HttpError,对于数据库操作错误,我们需要 DbError,对于搜索操作错误,我们需要 NotFoundError,等等

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!