ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

前端异常捕获与上报

2020-06-15 18:56:38  阅读:244  来源: 互联网

标签:错误 捕获 addEventListener window error 上报 data 前端


一、捕获的错误类型

  • 语法错误
  • 运行时异常
  • 资源加载异常
    • 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: 感谢巨人的肩膀使我们看的更远

 

标签:错误,捕获,addEventListener,window,error,上报,data,前端
来源: https://www.cnblogs.com/webcabana/p/13131769.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有