内容简介:windows下面的全局error事件程序,当有javaSript脚本运行错误或者资源<img>、<script>加载失败时,都会触发Event接口的error事件,也能被window.addEventListener捕获到这种方式应该是我们平时用的最多的,具体功能想必大家也应该都很清楚,将我们需要检测的代码包裹在try和catch中,当发生语法错误或者其他错误时,就会从catch里捕获到,而不管前端发生了什么,最后finally里的代码总会执行。下面的代码会怎么执行,大家可以思考一下
捕获错误的常见的几种方法
GlobalEventHandlers.onerror
windows下面的全局error事件程序,当有javaSript脚本运行错误或者资源<img>、<script>加载失败时,都会触发Event接口的error事件,也能被window.addEventListener捕获到
两种写法
window.onerror = function(message, source, lineno, colno, error) { console.log(message)//字符串错误信息 console.log(source)//发生错误的脚本 console.log(lineno)//发生错误的行号 console.log(colno)//发生错误的列号 console.log(error)//Erroe对象 return true//将代码错误定格在捕获阶段 } window.addEventListener('error', (msg, url, row, col, error) => { console.log( msg, url, row, col, error ); return true; }, true);
注意
- window.onerror只有在返回true时,异常才不会向上抛出,原理是冒泡机制。而且window.onerror是无法捕获到网络异常的,因为网络请求异常不会事件冒泡,虽然能在捕获阶段捕获到,但是无法判断HTTP的状态码,需要配合服务端才能排查。
- 我们平时写window.onerror的时候,最好写在最顶端,以免前面的错误脚本阻断了。同时在vue或者react框架中,他们有自身的错误捕获机制,所以会掩盖window.onerror,比如vue的Vue.config.errorHandler。想详细了解看官网文档即可。
try...catch...finally
这种方式应该是我们平时用的最多的,具体功能想必大家也应该都很清楚,将我们需要检测的代码包裹在try和catch中,当发生语法错误或者其他错误时,就会从catch里捕获到,而不管前端发生了什么,最后finally里的代码总会执行。
下面的代码会怎么执行,大家可以思考一下
try { try { throw new Error("oops"); } catch (ex) { console.error("inner", ex.message); throw ex; } finally { console.log("finally"); return; } } catch (ex) { console.error("outer", ex.message); }
特别注意
- try...catch只能捕获到运行时的非异步错误,而语法错误和异步错误就捕捉不到。
- 还有一点就是try..catch比较消耗性能,能少用的最好。
unhandledrejection
有些错误try..catch和windows.onerror也是无能为力的,比如说Promise实例从pending转变为rejected时,如果加了catch就会被捕获到,但要是没有加,那么继续抛出就会 Uncaught(in promise) Error
比如下面代码就捕获不到错误
window.onerror = function(message, source, lineno, colno, error) { console.log(message)//字符串错误信息 console.log(source)//发生错误的脚本 console.log(lineno)//发生错误的行号 console.log(colno)//发生错误的列号 console.log(error)//Erroe对象 return true//将代码错误定格在捕获阶段 } // 调用Promise.reject类方法 Promise.reject('promise error'); // 在工厂方法中调用reject方法 new Promise((resolve, reject) => { reject('promise error'); }); // 在工厂方法或then回调函数中抛异常 new Promise((resolve) => { resolve(); }).then(() => { throw 'promise error' });
我们可以通过下面的方法监听到
window.addEventListener('unhandledrejection', function (event) { // ...your code here to handle the unhandled rejection... // Prevent the default handling (such as outputting the // error to the console event.preventDefault(); });
但是这方法的兼容性有点失望
What the heck is "Script error"?
‘Script error’ 这个错误是比较常见的,一般通过windows.onerror捕获到后基本确实就是哪个script文件有问题,而且这个文件还是跨域的,既然是跨域导致信息不全,所以首先要解决的就是跨域问题,关于跨域方面的前端解决方案可以看我这篇文章《
对于script标签,我们还需要额外配置一个参数crossOrigin
<script src='www.example.com' crossorigin></script>
至于服务端,常用的就是
了解sourceMap
对于这个功能的讲解,看阮大神的
Navigator.sendBeacon() 存在的意义
平时我们很常见网页卡顿或者直接崩溃,一般是通过window 对象的 load 和 beforeunload 事件实现了网页崩溃的监控;具体看这篇文章, Logging Information on Browser Crashes
实现代码
window.addEventListener('load', function () { sessionStorage.setItem('good_exit', 'pending'); setInterval(function () { sessionStorage.setItem('time_before_crash', new Date().toString()); }, 1000); }); window.addEventListener('beforeunload', function () { sessionStorage.setItem('good_exit', 'true'); }); if(sessionStorage.getItem('good_exit') && sessionStorage.getItem('good_exit') !== 'true') { /* insert crash logging code here */ alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash')); }
但是上面的编码模式存在不友好的问题,当我们尝试在卸载页面前通过上传服务器数据,为了延迟页面卸载,需要通过同步XMLHttpRequest 发送数据或者创建一个几秒的循环来延迟卸载。这样的处理可想而知不是很友好,这时候sendBeacon()就横空出世了,很简单的实现向服务器发送数据,同时又不会影响下一个页面的加载,具体如下面简单的代码实现。
window.addEventListener('unload', logData, false); function logData() { navigator.sendBeacon("www.youAddress.com", analyticsData); }
扩展阅读
成熟解决方案
)
如果大神您想继续探讨或者学习更多知识,欢迎加入QQ或者微信一起探讨:854280588
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端错误监控与上报
- 前端性能优化之谈谈常见的性能指标及上报策略
- 在单页应用中,如何优雅的上报前端性能数据
- Flutter异常监测与上报
- 自定义错误上报的奇怪问题
- 强制DataNode向NameNode上报blocks
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。