JS中Try...Catch和onerror有什么区别?

JavaScript014

JS中Try...Catch和onerror有什么区别?,第1张

Try...Catch一般是用于控制台输出,是方便后台人员调试错误或处理异常的,可以自己写处理异常方法。

onerror是用于页面输出给客户端看的,好比密码不能小于6位等,会有个对应的resources.property文件的。

最近一直在做前端js错误监控的工作,在不断的打磨和完善中,发现里面还是知识点不少,现在就前端js错误监控做一些笔记和总结

我们知道前端js错误监控主要是利用了window.onerror函数来实现,onerror函数会在页面发生js错误时被调用。

我们可以看到函数正常是可以收集到错误字符串信息、发生错误的js文件,错误所在的行数、列数、和Error对象(里面会有调用堆栈信息等)。

我们只需要把这些信息回传到server端即可,再配合sourcemap的话我们就可以知道是源码中的哪一行出错了,从而实现完美的错误实时监控系统了。然而要完美还是需要做很多工作的。

首先,我们的js文件一般都是和网站不同域的,这是为了提高页面的渲染速度以及架构的可维护性(单独CDN域名,充分利用浏览器http并发数)。这样的js文件中发生错误我们直接监控你会发现你啥信息都收集不到。

实验一:我们的站点是 a.com ,页面中引用了两个js文件,一个是 a.com 域名下的a.js,一个是 b.com 域名下的b.js,我们在a.js文件中添加window.onerror监控,在b.js文件中主动抛出错误

我们可以看到下图的结果,onerror函数拿到的信息是 Script error, a 0 null ,啥卵用都没有,你完全不知道发生了什么错误,哪个文件发生的错误。

这是浏览器所做的安全限制措施,当加载自不同域(协议、域名、端口三者任一不同)的脚本中发生语法 (?) 错误时,为避免信息泄露,语法错误的细节将不会报告,而代之简单的 "Script error."

但是我们确实是需要知道发生错误的具体信息啊,不然监控就没有意义了。既然又是类同源限制的问题,那肯定是可以通过 CORS 来解决了。

实验二:我们给 b.js 加上 Access-Control-Allow-Origin:* 的response header,后面我们会发现还是没啥变化。

实验三:我们继续给 b.js 加上 crossorigin 属性,发现可以了,想要的信息都收集到了,nice

结论:如果想通过onerror函数收集不同域的js错误,我们需要做两件事:

注意: 以上两步缺一不可。实验二告诉我们,如果只是加上 Access-Control-Allow-Origin:* 的话,错误还是无法捕获。如果只加上crossorigin属性,浏览器会报无法加载的错误,如下图

可是。。。

如果你使用sentry的raven.js的话,你会发现你什么都不用做,他依然可以帮你捕获到一些错误的非常具体信息,确实是有点神奇啊,具体怎么做的?关键就是raven源码中的install方法中调用的_instrumentTryCatch函数起了作用,他通过tryCatch的方式wrap了一些关键函数,使得这些函数里的报错能够捕获,_instrumentTryCatch的具体实现原理我们后面再说

其实如果你真的什么都不做,raven也只是能捕获一些异步错误,同步错误还是无法捕获,所以你即使使用了sentry等第三方的错误收集库,你还是需要加上 Access-Control-Allow-Origin:* 和crossorigin属性

参考文献:

GlobalEventHandlers.onerror

What the heck is "Script error"?

事件:

是js中特有的东西。js就是基于事件驱动的一门语言。

想一下js的实现,都(大多数)是通过用户与浏览器的交互,比如你点击某个控件,鼠标放上,ajax请求等等,你的这些操作其实都是触发了js中定义的具体的事件,你可以给具体的事件绑定处理事件的函数。

我们常用的事件有:click,mouseover,mouseout等等。

事件属性:

表示的是具体的事件的一些特性,这些属性是让你更好的去控制这个事件,比如点击事件有属性可以判断点击的位置,点击时候是不是按下了哪个键盘按键,点击是鼠标左键还是鼠标右键。

关于事件的一些知识,强烈建议你去看下《javascript权威指南》,里面对事件,事件属性,事件目标,事件触发等等各种含义都解释的相当到位,相信你看了一定有帮助。

同时很希望帮到你,看到下面专家的回答,我压力还是蛮大的,真心希望我的回答能解决你的问题。