页面错误监控知识点

页面错误

前端错误分为JS运行时错误,接口错误,资源加载错误三种。

运行时错误捕获
  • 使用try/catch捕捉JS运行时错误。
  • 使用window.onerror捕获JS运行时错误。
  • 使用window.addEventListener('unhandledrejection')捕获未处理的promise reject错误。
  • 重写console.error捕获console.error错误。
var consoleError = window.console.error; 
window.console.error = function () { 
    alert(JSON.stringify(arguments)); // 自定义处理
    consoleError && consoleError.apply(window, arguments); 
};
  • 在跨域脚本上配置crossorigin="anonymous"捕获跨域脚本错误。
    CDN的HTTP Response头需增加Access-Control-Allow-Origin: *属性和Vary:Origin属性。
    引入JS文件的时候需在script标签上添加crossorigin属性。

接口错误捕获

重写window.XMLHttpRequest和window.fetch捕获请求错误。
XMLHttpRequest封装:

if(!window.XMLHttpRequest) return;
var xmlhttp = window.XMLHttpRequest;
var _oldSend = xmlhttp.prototype.send;
var _handleEvent = function (event) {
    if (event && event.currentTarget && event.currentTarget.status !== 200) {
          // 自定义错误上报 }
}
xmlhttp.prototype.send = function () {
    if (this['addEventListener']) {
        this['addEventListener']('error', _handleEvent);
        this['addEventListener']('load', _handleEvent);
        this['addEventListener']('abort', _handleEvent);
    } else {
        var _oldStateChange = this['onreadystatechange'];
        this['onreadystatechange'] = function (event) {
            if (this.readyState === 4) {
                _handleEvent(event);
            }
            _oldStateChange && _oldStateChange.apply(this, arguments);
        };
    }
    return _oldSend.apply(this, arguments);
}

fetch封装:

if(!window.fetch) return;
    let _oldFetch = window.fetch;
    window.fetch = function () {
        return _oldFetch.apply(this, arguments)
        .then(res => {
            if (!res.ok) { // True if status is HTTP 2xx
                // 上报错误
            }
            return res;
        })
        .catch(error => {
            // 上报错误
            throw error;  
        })
}
资源加载错误捕获

资源加载错误有可能是地址错误,网络不稳定,网络有代理。
使用window.addEventListener('error')捕获。window.onerror捕获不到资源加载错误。

window.onerror和window.addEventListener('error')的异同。
相同点:
都可以捕获到window上的js运行时错误。  
不同点:
1.捕获到的错误参数不同。   
2.window.addEventListener('error')可以捕获资源加载错误,但是window.onerror不能捕获到资源加载错误。  
上报方式
  • 动态创建img标签
 var win = window;
  var n = 'jsFeImage_' + _make_rnd(),
    img = win[n] = new Image();
  img.onload = img.onerror = function () {
    win[n] = null;
  };
  img.src = src;
  • 通过Ajax发送数据
压缩代码定位困难

基于 SourceMap 快速定位脚本报错方案
image

通过uglifyJs模拟webpack压缩的配置将JS文件进行压缩,得到source-map。
然后使用(sourceMap工具)[https://github.com/mozilla/source-map/]的SourceMapConsumer接口将转换后的行号列号传入Consumer得到原始错误位置信息。

var fs = require('fs')
var sourceMap = require('source-map')

// map文件
var rawSourceMapJsonData = fs.readFileSync('./dist/index.min.js.map', 'utf-8')
rawSourceMapJsonData = JSON.parse(rawSourceMapJsonData)

var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData);

// 打印出真实错误位置
console.log(consumer.originalPositionFor({line: 1, column: 220}))

参考:
https://segmentfault.com/a/1190000014672384#articleHeader2
https://segmentfault.com/a/1190000011041164

posted @ 2018-05-02 10:49  草珊瑚  阅读(416)  评论(0编辑  收藏  举报