前端异常捕获与上报

能捕获的错误类型

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

@font-face
background-image
...暂时无法捕获

捕获方式

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

代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <script src="http://baidu.com/test.js"></script>
</head>
<body>
    <img src="sss" onerror="javascript:console.log(this)">
    <div>hello world</div>

    <script type="text/javascript">
        function report() {
            (new Image()).src="http://post.error.com?data=xxx"
        }
        // DOM2
        // 全局捕获及时代码运行错误,比如语法错误、逻辑错误
        // 还有资源加载错误,通常是404或加载超时
        // 第三个参数一定true,为true表示在捕获阶段触发,为false就是冒泡阶段,那获取不到错误事件。
        window.addEventListener("error", function(ev) {
            console.log('捕获',ev)
        }, true);
        
        // DOM4
        // 捕获 Promise 未处理的异常
        window.addEventListener('unhandledrejection', function(e) {
            e.preventDefault();
            console.log('捕获到未处理的promise: ', e);
        }, false);
        new Promise((resolve, reject) => {
            reject('jiadsf');
        });
        fetch('http://example.com/movies.json')
        try {
            JSON.parse('{123123')   
        } catch (e) {
            // 捕获到JSON.parse的异常,虽然能全局捕获,但找不到错误对象ev.error
        }
        

    </script>
</body>
</html>

日志上报

简单版,使用图片。优点实现简单可跨域。

function report() {
    (new Image()).src="http://post.error.com?data=xxx"
}

进阶版,使用 Navigator.sendBeacon(),兼容性 Chrome 39+,IE 不兼容。

// navigator.sendBeacon(url, data);

navigator.sendBeacon('http://post.error.com', 'data=xxxxx');

// data 可以传递 string 类型,那么后端接口里接到的请求,Content-Type 为 text/plain,就当字符串处理data

此方法可用于满足统计和诊断代码的需要,可以批量发送数据,并且浏览器保证它不卡渲染线程,在页面 load/unload 事件里处理异步动作而不影响渲染,并且天然跨域。缺点只是兼容性了。

综上上报时优先使用 sendBeancon,监测到不兼容则用 img。

function reportData(url, data) {
    if (navigator.sendBeacon) {
        navigator.sendBeacon(url, data);
    } else {
        (new Image()).src = `${url}?data=${data}`
    }
}

export default reportData;

参考

MDN-Navigator.sendBeacon()

前端异常监控-看这篇就够了

使用sendBeacon进行前端数据上报

猜你喜欢

转载自www.cnblogs.com/everlose/p/12538593.html