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 相关文章推荐
Jquery 弹出层插件实现代码
Oct 24 Javascript
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
Jul 10 Javascript
JS获取节点的兄弟,父级,子级元素的方法
Jan 09 Javascript
JS数组(Array)处理函数整理
Dec 07 Javascript
JavaScript基础知识之方法汇总结
Jan 24 Javascript
javascript正则表达式之分组概念与用法实例
Jun 16 Javascript
jQuery实现简单的滑动导航代码(移动端)
May 22 jQuery
vue2.0的contextmenu右键弹出菜单的实例代码
Jul 24 Javascript
微信小程序后端实现授权登录
Feb 24 Javascript
js Math数学简单使用操作示例
Mar 13 Javascript
微信小程序实现弹框效果
May 26 Javascript
vue实现分页的三种效果
Jun 23 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
洪恩在线成语词典小偷程序php版
2012/04/20 PHP
PHP用正则匹配form表单中所有元素的类型和属性值实例代码
2017/02/28 PHP
js动态删除div元素基本思路及实现代码
2014/05/08 Javascript
javascript搜索框效果实现方法
2015/05/14 Javascript
jQuery超赞的评分插件(8款)
2015/08/20 Javascript
基于Jquery和html5的7款个性化地图插件
2015/11/17 Javascript
JQuery用户名校验的具体实现
2016/03/18 Javascript
jQuery EasyUI框架中的Datagrid数据表格组件结构详解
2016/06/09 Javascript
微信小程序  wx.request合法域名配置详解
2016/11/23 Javascript
vue动态组件实现选项卡切换效果
2017/03/08 Javascript
Javascript 实现匿名递归的实例代码
2017/05/25 Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
2017/08/15 Javascript
使用js获取伪元素的content实例
2017/10/24 Javascript
nodejs实现截取上传视频中一帧作为预览图片
2017/12/10 NodeJs
Vue页面骨架屏注入方法
2018/05/13 Javascript
如何使用CSS3+JQuery实现悬浮墙式菜单
2019/06/18 jQuery
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
python单线程实现多个定时器示例
2014/03/30 Python
python写的一个squid访问日志分析的小程序
2014/09/17 Python
对Python3+gdal 读取tiff格式数据的实例讲解
2018/12/04 Python
自定义Django Form中choicefield下拉菜单选取数据库内容实例
2020/03/13 Python
解决Django no such table: django_session的问题
2020/04/07 Python
django rest framework serializers序列化实例
2020/05/13 Python
解决c++调用python中文乱码问题
2020/07/29 Python
python中的split、rsplit、splitlines用法说明
2020/10/23 Python
详解python定时简单爬取网页新闻存入数据库并发送邮件
2020/11/27 Python
CSS3条纹背景制作的实战攻略
2016/05/31 HTML / CSS
澳大利亚小众服装品牌:Maurie & Eve
2018/03/27 全球购物
大学四年的个人自我评价
2014/01/14 职场文书
迟到检讨书1000字
2014/01/15 职场文书
护理专业大学生自我推荐信
2014/01/25 职场文书
物业项目经理岗位职责
2015/04/01 职场文书
防卫过当辩护词
2015/05/21 职场文书
2015年暑期社会实践方案
2015/07/14 职场文书
彩虹社八名人气艺人全新周边限时推出,性转女装男装一次拥有!
2022/04/01 日漫
vue elementUI表格控制对应列
2022/04/13 Vue.js