汪微的博客
zane,做一个有思维的开发者

汪微的博客

web-report-sdk升级之页面后续操作中Error捕捉与AJAX性能上报方式实现(支持单页面应用程序)

2019年03月21日188 browse

web-report-sdk(浏览器端性能上报sdk)是一款浏览器端页面性能,ajax,fetch ,错误信息,资源性能上报SDK,资源小巧,性能强悍。

同时它还实现了页面再后续操作中出现的Error信息上报,和ajax性能数据的上报。并完美支持单页面应用程序。

如果你对它感兴趣,下面链接是github传送门 (瞅瞅去😎):

https://github.com/wangweianger/web-report-sdk


以下内容围绕以下几点来阐述:

  • 浏览器端错误上报监听方式
  • 浏览器端ajax拦截方式
  • 在无代码侵入情况下如何判断是页面加载时的ajax还是用户后续操作中的ajax请求,(error同理)并考虑兼容单页面应程序
  • 应该在何处何时上报才合理,(例如:一次点击操作进行了3次ajax请求,应该在何时进行上报,如何保证上报的完整性和不重复性)


浏览器端错误监听方式

一、onerror事件

  • 当JavaScript运行时错误(包括语法错误)发生时,window会触发一个ErrorEvent接口的error事件,并执行window.onerror()。

  • 当一项资源(如<img>或<script>)加载失败,加载资源的元素会触发一个Event接口的error事件,并执行该元素上的onerror()处理函数。这些error事件不会向上冒泡到window,不过能被单一的window.addEventListener捕获。

因此我们监听error上报有两种写法:

1、监听运行的script脚本错误

window.onerror = function(message, source, lineno, colno, error){
    const json = {
        msg: message,
        resourceUrl:source,
        line:lineno,
        col:colno
    }
    report(json);
};

函数参数:

  • message:错误信息(字符串)。可用于HTML onerror=""处理程序中的event
  • 发生错误的脚本URL(字符串)

  • 发生错误的行号(数字)

  • 发生错误的列号(数字)

  • Error对象(对象)


2、监听如 (<img>或<script>)错误信息

window.addEventListener('error',function(e){
    if (e.target != window) {
        const josn = {
            msg: e.target.localName,
            resourceUrl:e.target.href || e.target.currentSrc,
            type: e.type,
        };
        report(json);
    }
},true);

备注: e.target != window 是为了只监听img或者script等资源错误信息。


二、unhandledrejection事件,捕捉Promise未被处理的reject信息

window.addEventListener('unhandledrejection', function (e) {
    const error     = e && e.reason
    const message   = error.message || '';
    const stack     = error.stack || '';

    let resourceUrl, col, line;
    let errs = stack.match(/(.+?)/)
    if (errs && errs.length) errs = errs[0]
    errs = errs.replace(/w.+[js|html]/g, $1 => { resourceUrl = $1; return ''; })
    errs = errs.split(':')
    if (errs && errs.length > 1) {
        line = parseInt(errs[1] || 0); 
        col = parseInt(errs[2] || 0);
    } 
    
    const josn = {
        msg: message,
        resourceUrl: resourceUrl,
        line: col,
        col: line
    }

    report(json);
})


根据以上三种处理方式,几乎可以捕捉绝大部分的错误信息,各种框架都有自己的错误捕捉方式,不在此讨论范围之类。


浏览器端AJAX请求拦截方式

ajax拦截方式再这里不做详细的讨论,总结下来无非下面这几种处理方式。
  • 重写XMLHttpRequest对象,使用call、apply的能力去拦截open、onload、onerror和onreadystatechange方法,从而得到性能和错误信息
  • 使用Object.defineProperty把XMLHttpRequest变成观察者对象,get和set时触发相应的函数从而获得性能和错误信息
  • 重写fetch、jquery、axios等对象,拦截他们的then和catch事件从而获得性能和错误信息


具体实现可参考以下链接内容:

浏览器性能、XMLHttpRequest、jquery、fetch、axios、错误信息上报sdk

https://github.com/wangweianger/web-report-sdk

一个拦截XMLHttpRequest请求的精简库

https://github.com/wendux/Ajax-hook


如何判断是页面加载时的AJAX|Error还是后续操作中的AJAX|Error (需要考虑带页面应用程序)

编辑中...


应该在何处何时上报才合理

编辑中...



博主 zane 发表于 2019-03-21 19:11:26,添加在了 javascript 标签下

打赏

您的支持将鼓励我继续努力与分享。

扫码打赏,建议金额1-10元

提醒:打赏金额将直接进此方账号,无法退款,请您谨慎操作。

评论

正在加载验证码......

提交

ni'hao

2019-05-23 23:02:23