前端错误监控

为何要作前端错误监控?

1. 为了保证产品的质量前端

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

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>
相关文章
相关标签/搜索