• 前端错误监控


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

    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>
  • 相关阅读:
    iOS 即时通讯 + 仿微信聊天框架 + 源码
    Accelerate Framework in Swift
    最新 iOS 框架整体梳理(三)
    最新 iOS 框架整体梳理(二)
    单元测试
    iOS
    画个Shape留意到的东西
    deleteSections & deleteRows 我踩的坑
    常用开发技巧系列(六)
    程序员该如何提高睡眠质量?—程序媛233酱的助攻~
  • 原文地址:https://www.cnblogs.com/cythia/p/11093231.html
Copyright © 2020-2023  润新知