JavaScript代码异常监控实现过程详解


Posted in Javascript onFebruary 17, 2020

这篇文章主要介绍了JavaScript代码异常监控实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

JavaScript异常一般有两方面:语法错误和运行时错误。两种错误的捕获和处理方式不同,从而影响具体的方案选型。通常来说,处理JS异常的方案有两种:try...catch捕获 和 window.onerror捕获。以下就两种方案分别分析各自的优劣。

虽然语法错误本应该在开发构建阶段使用测试工具避免,但难免会有马失前蹄部署到线上的时候。

try...catch捕获

这种方案要求开发人员在编写代码的时候,在预估有异常发生的代码段使用try...catch,在发生异常时将异常信息发送给接口:

try{
//可能发生异常的代码段
}catch(e){
//将异常信息发送服务端
}

try...catch的优点是可以细化到每个代码块,并且可以自定义错误信息以便统计。

具体到上文提到的两种js异常,try...catch无法捕获语法错误,当遇到语法错误时,浏览器仍然会抛出错误Uncaught SyntaxError,但是不会被捕获,不会走进catch的代码块内。

另外,如果try代码块中有回调函数也不会被捕获,比如:

try{
var btn = $('#btn');
  btn.on('click',function(){
    //throw error
  });
}catch(e){}

上述代码中btn的监听函数里抛出的异常无法被外层的catch捕获到,必须额外套一层:

try{
var btn = $('#btn');
  btn.on('click',function(){
    try{
      //throw error
    }catch(e){}
  });
}catch(e){}

综上所述,try...catch方案的部署非常复杂,如果人工部署除了要求巨量的工作量,还跟开发人员的能力和经验有关。如果依赖编译工具部署(比如fis),那每个代码块都套一层try...catch也是非常难看的并且容易引发一些不可预估的问题。

window.onerror捕获

这种方式不需要开发人员在代码中书写大量的try...catch,通过给window添加onerror监听,在js发生异常的时候便可以捕获到错误信息,语法异常和运行异常均可被捕获到。但是window.onerror这个监听必须放在所有js文件之前才可以保证能够捕获到所有的异常信息。

window.onerror事件的详细信息参考这里。

/**
 * @param {String} errorMessage  错误信息
 * @param {String} scriptURL   出错文件的URL
 * @param {Long}  lineNumber   出错代码的行号
 * @param {Long}  columnNumber  出错代码的列号
 * @param {Object} errorObj    错误信息Object
 */
window.onerror = function(errorMessage, scriptURL, lineNumber,columnNumber,errorObj) { 
  // code..
}

onerror的实现方式各浏览器略有差异,但是前三个参数都是相同的,某些低版本浏览器没有后两个参数。

最后一个参数errorObj各浏览器实现的程度不一致,具体可参考这里。

下图是被onerror捕获到的一个异常的具体信息:

JavaScript代码异常监控实现过程详解

综上所述,window.onerror方案的优点是减少了开发人员的工作量,部署方便,并且可以捕获语法错误和运行错误。缺点是错误信息不能自定义,并且errorObj每种浏览器的实现有略微差异,导致需统计的信息有局限性。

跨域JS文件异常的捕获

为了提高web性能,目前大部分web产品架构中都有CDN这一环,将资源部署到不同的域名上,充分利用浏览器的并发请求机制。那么在跨域JS文件中发生异常的时候,onerror监听会捕获到什么信息呢?请看下图:

JavaScript代码异常监控实现过程详解

只有一个稍微有价值的信息Script error,其他什么信息都没有,为什么会这样呢?

我们都知道浏览器有同源资源限制,常规状态下是无法进行跨域请求的。而script、img、iframe标签的src属性是没有这种限制的,这也是很多跨域方案的基础。但是即使script标签可以请求到异域的js文件,此文件中的信息也并不能暴露到当前域内,这也是浏览器的安全措施所致。

那么有没有办法获取到异域资源的异常信息呢?

其实很简单,目前可以说基本上所有的web产品对于js/css/image等静态资源都在服务端设置了Access-Control-Allow-Origin: *的响应头,也就是允许跨域请求。在这个环境下,只要我们在请求跨域资源的script标签上添加一个crossorigin属性即可:

<script src="http://static.toutiao.com/test.js" crossorigin></script>

这样的话,异域的test.js文件中发生异常时便可以被当前域的onerror监听捕获到详细的异常信息。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Iframe thickbox2.0使用的方法
Mar 05 Javascript
javascript基础知识大集锦(一) 推荐收藏
Jan 13 Javascript
js中的cookie的读写操作示例详解
Apr 17 Javascript
用window.onerror捕获并上报Js错误的方法
Jan 27 Javascript
vue.js组件vue-waterfall-easy实现瀑布流效果
Aug 22 Javascript
vue.js实现只弹一次弹框
Jan 29 Javascript
Webpack devServer中的 proxy 实现跨域的解决
Jun 15 Javascript
vue实现移动端悬浮窗效果
Dec 01 Javascript
深入理解Antd-Select组件的用法
Feb 25 Javascript
Vue watch响应数据实现方法解析
Jul 10 Javascript
JS+CSS实现过渡特效
Jan 02 Javascript
react项目从新建到部署的实现示例
Feb 19 Javascript
windows下create-react-app 升级至3.3.1版本踩坑记
Feb 17 #Javascript
npx create-react-app xxx创建项目报错的解决办法
Feb 17 #Javascript
Vue的双向数据绑定实现原理解析
Feb 17 #Javascript
JavaScript函数Call、Apply原理实例解析
Feb 17 #Javascript
javascript异常处理实现原理详解
Feb 17 #Javascript
Vue+webpack实现懒加载过程解析
Feb 17 #Javascript
javascript History对象原理解析
Feb 17 #Javascript
You might like
wordpress网站转移到本地运行测试的方法
2017/03/15 PHP
基于jQuery的公告无限循环滚动实现代码
2012/05/11 Javascript
JS将制定内容复制到剪切板示例代码
2014/02/11 Javascript
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
JS实现可拖曳、可关闭的弹窗效果
2015/09/26 Javascript
jQuery Validate表单验证深入学习
2015/12/18 Javascript
jQuery基础知识点总结(DOM操作)
2016/06/01 Javascript
Bootstrap中的Panel和Table全面解析
2016/06/13 Javascript
Node.js中常规的文件操作总结
2016/10/13 Javascript
javaScript语法总结
2016/11/25 Javascript
使用JavaScript实现alert的实例代码
2017/07/06 Javascript
Vue组件通信之Bus的具体使用
2017/12/28 Javascript
jquery 输入框查找关键字并提亮颜色的实例代码
2018/01/23 jQuery
vue中element组件样式修改无效的解决方法
2018/02/03 Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
2018/02/09 Javascript
Node.js使用supervisor进行开发中调试的方法
2019/03/26 Javascript
layui table数据修改的回显方法
2019/09/04 Javascript
Vue+Element-UI实现上传图片并压缩
2019/11/26 Javascript
微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示功能的实现
2020/07/22 Javascript
Vue Object.defineProperty及ProxyVue实现双向数据绑定
2020/09/02 Javascript
Python的lambda匿名函数的简单介绍
2013/04/25 Python
修改Python的pyxmpp2中的主循环使其提高性能
2015/04/24 Python
为Python的web框架编写前端模版的教程
2015/04/30 Python
python妹子图简单爬虫实例
2015/07/07 Python
Python实现SVN的目录周期性备份实例
2015/07/17 Python
Python远程视频监控程序的实例代码
2019/05/05 Python
python set内置函数的具体使用
2019/07/02 Python
python读出当前时间精度到秒的代码
2019/07/05 Python
Python使用正则表达式分割字符串的实现方法
2019/07/16 Python
Django 创建新App及其常用命令的实现方法
2019/08/04 Python
英国领先的在线旅游和休闲零售商:lastminute.com
2019/01/23 全球购物
Bed Bath & Beyond加拿大官网:购买床上用品、浴巾、厨房电器等
2019/10/04 全球购物
毕业生精彩的自我评价分享
2013/10/06 职场文书
运动会方阵解说词
2014/02/12 职场文书
项目经理任命书
2014/06/04 职场文书
来探秘“德国中小企业”的成功之道
2019/07/26 职场文书