页面错误
前端错误分为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 快速定位脚本报错方案
通过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