SDK
- Badjs
- Sentry
-
为什么做前端监控?
项目体系庞大,包括后台管理,小程序,app使用第三方库上报成本费用。
- 快速定位线上环境的问题所在(定位用户行为链及设备环境)。
提供数据指标去衡量,比如功能使用率、性能指标等,调优策略和量化指标。
监控什么?
前端监控采集的内容主要包括行为分析、异常监控、性能监控等。
其行为分析主要有:页面的进入、离开、点击、滚屏、自定义事件。
采集哪些数据?
用户行为:1. 用户页面操作;2. 页面跳转;3. 网络请求;4. 自定义事件;5. 控制台输出。
- 错误数据:1. 后端接口报错;2. 前端js报错。
怎么收集上报?
| 捕获方式\异常类型 | 同步 | 异步 | (网络异常)资源加载 | promise | async/await |
|---|---|---|---|---|---|
| try/catch | 1 | 1 | |||
| window.onerror | 1 | 1 | |||
| error addEventListener请注意最后一个参数是true - true - 事件句柄在捕获阶段执行 - false- 默认。事件句柄在冒泡阶段执行 |
1 | 1 | 1 | ||
| unhandledrejection | 1 | 1 | |||
| iframe | |||||
| react/vue 三方库的捕获 |
- try catch(引用错误)

语法错误



- onerror, 对于 onerror 这种全局捕获,最好写在所有 JS 脚本的前面,因为你无法保证你写的代码是否出错,如果写在后面,一旦发生错误的话是不会被 onerror 捕获到的。
同步
*被格式化后的语法错误;被解析为一条语句的。

异步
:::info
- window.onerror 可以捕获常见语法、同步、异步错误等错误;
- window.onerror 无法捕获 Promise 错误、网络错误;
- window.onerror 应该在所有JS脚本之前被执行,以免遗漏;
- window.onerror 容易被覆盖,在处理回调时应该考虑,别人也在使用该事件监听。 :::
- 资源加载(error 可捕获 但是无法捕获状态码)


:::info
- 通过js创建img标签并设置src属性,但是并没有插入文档中,当加载异常时,addEventListener 不能捕获异常。 :::
- Promise 全局异常捕获事件 unhandledrejection(event.preventDefault(); 防止默认处理,去除控制台异常显示)。
当Promise 被 reject 且没有 reject 处理的时候,会触发 unhandledrejection 事件

- iframe 异常

:::info
- 同源的iframe 可以通过 window.frames[0].onerror。
- 非同源可能是postMessage通信。
:::
React:
错误边界(Error Boundaries)react15 中unstable_handleError不再起作用,react16 componentDidCatch中捕获。


Vue:

使用未定义属性
点击时触发
err指代 error 对象,info是一个 Vue 特有的字符串,vm指代 Vue 应用本身。
- errorHandler |
图1触发 | ||
|---|---|---|---|
- warnHandler |
生产环境不起作用。 | 图2触发 | |
- renderError |
组件级别,只适用于非生产环境。 | 图1触发 | |
- errorCaptured |
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。 | 当子组件发生错误,图1,图2类型错误都可触发父组件 errorCaptured。 |
点击事件(用户页面操作)
请求 监听 XMLHttpRequest onreadystatechange

链接跳转(针对页面跳转,如前进、后退)
window.onpopstate是popstate事件在window对象上的事件处理程序。
针对控制台打印,可以重写其info、warn、error方法

上报方式?
- 自动上报(全局捕获)
手动上报(业务中自定义上报) :::info 数据上报两种:一种是Ajax的方式上报;另一种是通过Image的形式进行上报。目前很多大厂采用的上报方式均是通过一个1*1像素的的gif图片进行上报。
为什么采用Image的方式上报?
- 没有跨域问题。因为数据服务器和后端服务器大概率是不同的域名,若采用Ajax的方式进行处理还要处理跨域问题,否则数据会被浏览器拦截。
- 不会阻塞页面加载,只需new Image对象即可。
图片类型很多,为什么采用gif这种格式进行上报?
对于1*1px的图片,BMP结构的文件需要74字节,PNG结构的文件需要67字节,GIF结构的文件只需要43字节。同样的响应,GIF可以比BMP节约41%的流量,比PNG节约35%的流量,所以选择gif进行上报。 :::数据展示?
可视化报表
-
总结
异常一共七大类,处理时需分清是致命错误还是非致命错误。
可疑区域增加 try-catch
- 全局监控 JS 异常 window.onerror
- 全局监控静态资源异常 window.addEventListener
- 捕获没有 catch 的 Promise 异常用 unhandledrejection
- Vue errorHandler 和 React componentDidCatch
- Axios 请求统一异常处理用拦截器 interceptors
- 使用日志监控服务收集用户错误信息

