产品上线前我们有各种手段来进行测试,确保产品质量可靠,达到可上线标准。但上线之后就真的没有问题了吗?真实情况大多是上线前各种测试没有任何问题,上线后用户反馈出了各种bug,而你根据反馈怎么整都复现不出来。崩溃不崩溃!!!

如何进行错误监控,就是这节要聊的主题,线上出现问题后,及时进行错误收集,bug分析。

# 错误分类

  • 及时运行错误 :即代码执行过程中的错误
  • 资源加载错误 :脚本加载失败,图片加载失败....;资源加载错误不冒泡

# 捕获错误

# 针对及时运行错误

  • try...catch看我这个介绍

  • window.onerron

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
     <script>
      window.onerror = e => {
        console.error('错误监控', e)
      }
    </script>
    </body>
    </html>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    注意这段用来监控执行过程中的错误的 JS 代码,需要写在其他 JS 引入的开头;

    且对于其他通过外链引入的JS文件,执行错误只能打印出 Script error. 无法打印出更多的错误信息。

# 针对资源加载错误

  • Error 事件捕获

    window.addEventListener('error', e => {
      console.log('错误监听', e);
    }, true);
    
    1
    2
    3

    我们通过 window.onerror 无法监听到资源加载错误,是因为 window.onerror 是在事件冒泡阶段执行的,而资源加载错误不冒泡,所以无法监听;

    但是通过 window.addEventListener('error', () => {}, true) 我们可以选择让监听在捕获阶段执行,自然就可以监听到了。

    如果在代码中进行了错误处理,没有将错误向外抛,那么无论怎样,也监听不到错误;例如:

    try {} catch (err) {
      console.error(err);
    }
    
    1
    2
    3

    你在控制台会看到报错,但你错误监控却没有执行。如果同时想要在错误监控中收集到,你需要将错误抛出去,上面的代码可以这样修改:

    try {} catch (err) {
      console.error(err);
      throw new Error(err);
    }
    
    1
    2
    3
    4
  • Object.onerror : 给资源加载添加 onerror 事件

    <img src="https://www.github.com/static/xxxxx.png" onerror="handleImgErr()" alt="" srcset="">
    <video src="https://www.gitee.com/staic/xxxx.mp4" onerror="handleVideoErr()"></video>
    
    1
    2
    const handleImgErr = e => {
      console.log('img加载错误.错误内容:', e);
    }
    const handleVideoErr = e => {
      console.log('video加载错误,错误内容:', e);
    }
    
    1
    2
    3
    4
    5
    6
  • performance.getEntries

    performance介绍看这里

    performance.getEntries介绍看这里

    getEntries() 可以拿到所有已经加载成功的资源,document.getElementsByTagName('有加载资源的标签') 可以拿到所有需要加载资源的标签,做个减法就可以得到那些资源没有加载成功。

    // 以获取加载图片失败的数量为例
    const loadSucImgTotal = performance.getEntries().filter(item => item.initiatorType === 'img').length;
    const allLoadImgTotal = document.getElementsByTagName('img').length;
    
    const failImgTotal = allLoadImgTotal - loadSucImgTotal;
    
    1
    2
    3
    4
    5

    performance.getEntries 确实可以间接的拿到资源加载的错误,但很明显,它只是解决问题的一种途径,但并不是特别好的途径

# 跨域的JS资源错误

对于不同源的JS资源,上面的代码可以监听到错误,但无法拿到错误内容

  • 错误提示

    image-20200212175525643

  • 解决方法

    1. script 标签增加crossorigin 属性
    2. 在设置JS资源响应Access-Control-Allow-Origin: *

# 错误上报

# 使用AJAX上报

# 借助Image对象上报

一行代码,借助Image 构造函数 生成一个image 对象,src 属性填写你上报错误的接口,直接发送请求上报错误。

(new Image()).src = '填写你上报错误的接口,参数拼后面'
1

重点:

很明显使用 **`Image`** 进行错误上报,简单又方便,所以不仅仅是应对面试,在真实的需要进行错误收集的场景中,第一选择也应该是 **`Image`**
Last Updated: 2020-4-27 22:56:04