# 前端代码异常监控方案
前端代码异常主要有两种情况:
- 1、Js脚本里存在着语法错误;
- 2、js脚本在运行时发生错误。
# 1、try...catch
- 无法捕捉到语法错误和异步错误,只能捕捉运行时错误;
- 可以拿到出错的信息,堆栈,出错的文件、行号、列号;
- 需要借助工具把所有的
function
以及文件加入try...catch
,可以在这个阶段打入更多的静态信息。 - 需要在捕获异常的代码上进行包裹,会导致页面臃肿不堪,不适用于整个项目的异常捕获。
# 2、window.onerror
- 即可以捕捉到语法错误(无论异步还是非异步),也可以捕捉到运行时错误;
- 可以拿到出错的信息、堆栈,出错的文件、行号和列号;
- 只要在当前页面执行的js脚本出错都会被捕捉到;
- 跨域额资源需要特殊头部支持,在
script
标签中配置crossorigin
属性,服务器添加Access-Control-Allow-Origin
。 注意 window.onerror
只有函数在返回true
的时候,异常才不会向上抛出,否者即使是知道异常单额发生,控制台还是会显示Uncaught Error: xxxxx
。window.onerror
无法捕获到网络异常的错误。
# 3、Promise错误
Promise 实例抛出异常而你没有用 catch 去捕获的话,onerror 或 try-catch 也无能为力,无法捕捉到错误。 所以你最好添加一个 Promise 全局异常捕获事件 unhandledrejection
。
window.addEventListener("unhandledrejection", function(e){
e.preventDefault()
console.log('我知道 promise 的错误了');
console.log(e.reason);
return true;
});
1
2
3
4
5
6
2
3
4
5
6
# 4、iframe 错误
父窗口直接使用 window.onerror 是无法直接捕获,如果你想要捕获 iframe 的异常的话,有分好几种情况。 1) 如果你的 iframe 页面和你的主站是同域名的话,直接给 iframe 添加 onerror 事件即可。
<iframe src="./iframe.html" frameborder="0"></iframe>
<script>
window.frames[0].onerror = function (msg, url, row, col, error) {
console.log('我知道 iframe 的错误了,也知道错误信息');
console.log({
msg, url, row, col, error
})
return true;
};
</script>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
2)如果你嵌入的 iframe 页面和你的主站不是同个域名的,但是 iframe 内容不属于第三方
可以通过与 iframe 通信的方式将异常信息抛给主站接收。与 iframe 通信的方式有很多,常用的如: postMessage,hash 或者 name字段跨域等等
参考链接
前端异常监控、上报及js压缩代码定位 (opens new window) 3)如果是非同域且网站不受自己控制的话,除了通过控制台看到详细的错误信息外,没办法捕获
# 5、监控上报
监控拿到报错信息之后,接下来就需要将捕捉到的错误信息发送到信息收集平台上,常用的发送形式主要有两种:
- 通过 Ajax 发送数据
- 动态创建 img 标签的形式
function error(msg,url,line){
var REPORT_URL = "xxxx/cgi"; // 收集上报数据的信息
var m =[msg, url, line, navigator.userAgent, +new Date];// 收集错误信息,发生错误的脚本文件网络地址,用户代理信息,时间
var url = REPORT_URL + m.join('||');// 组装错误上报信息内容URL
var img = new Image;
img.onload = img.onerror = function(){
img = null;
};
img.src = url;// 发送数据到后台cgi
}
// 监听错误上报
window.onerror = function(msg,url,line){
error(msg,url,line);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14