zoukankan      html  css  js  c++  java
  • 前端异常捕获与上报

    一、捕获的错误类型

    • 语法错误
    • 运行时异常
    • 资源加载异常
      • img
      • script
      • link
      • audio
      • video
      • iframe
      • ...外链资源的DOM元素
    • 异步请求异常
    • Promise异常
    • CSS中资源异常
      • font-face
      • background-image         

    二、捕获方式

    • try-catch
    • window.onerror = cb (DOM0)
    • window.addEventListener('error', cb, true) (DOM2)
    • window.addEventListener("unhandledrejection", cb) (DOM4)
    • Promise.then().catch(cb)
    • 定制异步请求代码

    三、错误上报相关问题

    • 获取不到具体错误
      • 跨域调用js,由于浏览器的安全策略,只会返回 Script error. ;通过添加crossorigin来解决; image 和 script 标签都有 crossorigin 参数,它的作用就是告诉浏览器,我要加载一个外域的资源,并且我信任这个资源;服务器也需要设置 Access-Control-Allow-Origin 的响应头;
      • 生产环境代码都被压缩打包,可以在打包代码时相应添加一些空格,虽然不能定位到具体位置,不过通过行数,可以获得具体哪个文件出了错,缩小排查范围;
    • 收集的采样率
      • 没有必要将所有的错误信息全部送到 Log 中,这个量太大了。如果网页 PV 有 1kw,那么一个必现错误发送的 log 信息将有 1kw 条,大约一个 G 的日志。我们可以给 Reporter 函数添加一个采样率;
        function needReport (sampling){
          // sampling: 0 - 1
          return Math.random() <= sampling;
        }
        Reporter.send = function(errInfo, sampling) {
          if(needReport(sampling || 1)){
            Reporter._send(errInfo);
          }
        };
    • 尽量少的使用try..catch,如果要使用请使用尽量干净的作用域;
    • 错误的报警与提示
      • 错误超过阈值,比如 10分钟最多允许 100 个错误,结果超过了 100
      • 错误超过平均值的 10 倍,超过平均值就报警,这个逻辑显然不正确,但是超过了平均值的 10 倍,基本可以认定服务出问题了
      • 在纳入对比之前,要过滤同 IP 出现的错误,比如一个错误出现在 for 循环或者 while 循环中,再比如一个用户在蹲点抢购,不停的刷新
    • 上报方式
      • 优点实现简单可跨域;
        // 简单可跨域
        function report() {
            (new Image()).src="http://post.error.com?data=xxx"
        }
        进阶版,使用 Navigator.sendBeacon()
      • // navigator.sendBeacon(url, data);
        navigator.sendBeacon('http://post.error.com', 'data=xxxxx');
        // data 可以传递 string 类型,那么后端接口里接到的请求,Content-Type 为 text/plain,就当字符串处理data
        // 此方法可用于满足统计和诊断代码的需要,可以批量发送数据,并且浏览器保证它不卡渲染线程,在页面 load/unload 事件里处理异步动作而不影响渲染,并且天然跨域。缺点只是兼容性了
      • 兼容版
        function reportData(url, data) {
            if (navigator.sendBeacon) {
                navigator.sendBeacon(url, data);
            } else {
                (new Image()).src = `${url}?data=${data}`
            }
        }
        export default reportData;  
    •  几种上报方法
      • window.addEventListener("error", function(e) {
            var eventType = [].toString.call(e, e);
            if (eventType === "[object Event]") { // 过滤掉运行时错误
              // 上报加载错误 可以获取资源加载错误
           console.log(ev.target);
             report(ev)
            } 
        }, true );    
      • window.onerror = function (msg, url, lineNo, columnNo, error) { 
           // 捕捉错误
           console.log(msg, url, lineNo, columnNo, error)
         }
      • window.addEventListener("unhandledrejection", function (event) {
            // 捕获违背catch的reject
            console.log(event)
            console.log(event.reason);
            event.preventDefault();
            // window.addEventListener('error')捕获资源加载错误。因为它也能捕获js运行时错误,为避免重复上报js运行时错误,此时只有event.srcElement inatanceof HTMLScriptElement或HTMLLinkElement或HTMLImageElement时才上报
        }); 
      • //window.onerror和window.addEventListener('error')的异同
        //相同点是都可以捕获到window上的js运行时错误。
        //区别是1.捕获到的错误参数不同 
        //     2.window.addEventListener('error')可以捕获资源加载错误,但是window.onerror不能捕获到资源加载错误

    四、平台的搭建

    • 待补充。。。 

     ps: 感谢巨人的肩膀使我们看的更远

  • 相关阅读:
    iOS 5.0 后UIViewController新增:willMoveToParentViewController和didMoveToParentViewCon[转]
    数字统计(0)<P2010_1>
    数字反转(0)<P2011_1>
    质因数分解(0)<P2012_1>
    记数问题(0)<P2013_1>
    珠心算测验(0)<P2014_1>
    金币(0)<P2015_1>
    归并排序
    循环语句(while语句和do...while语句)
    循环语句(for语句的用法)
  • 原文地址:https://www.cnblogs.com/webcabana/p/13131769.html
Copyright © 2011-2022 走看看