# 前端代码异常监控方案

前端代码异常主要有两种情况:

  • 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

# 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)如果你嵌入的 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
Last Updated: 8/19/2020, 11:38:52 PM