window.onerror的总结

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

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

window.onerror = function(message, source, lineno, colno, error) { ... }

我们可以看到函数正常是可以收集到错误字符串信息、发生错误的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文件中主动抛出错误

<!-- index.html  -->
<script type="text/javascript" src="http://a.com/a.js" ></script>
<script type="text/javascript" src="http://b.com/b.js" ></script>
// a.js
window.onerror = function (message, url, line, column, error) {
  console.log('log---onerror::::',message, url, line, column, error);
}
// b.js
throw new Error('this is the error happened in b.js');

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

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

实验一的结果

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

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

实验二的结果

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

<!-- index.html  -->
<script type="text/javascript" src="http://a.com/a.js" ></script>
<script type="text/javascript" src="http://b.com/b.js"  crossorigin></script>
实验三的结果

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

  1. 相关的js文件上加上Access-Control-Allow-Origin:*的response header
  2. 引用相关的js文件时加上crossorigin属性

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

仅仅加上crossorigin属性的script加载结果

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

    install: function() {
        var self = this;

        if (self.isSetup() && !self._isRavenInstalled) {
            TraceKit.report.subscribe(function () {
                self._handleOnErrorStackInfo.apply(self, arguments);
            });
            if (self._globalOptions.instrument && self._globalOptions.instrument.tryCatch) {
              self._instrumentTryCatch();// 通过tryCatch来wrap关键函数,从而获得error的具体信息
            }

            if (self._globalOptions.autoBreadcrumbs)
                self._instrumentBreadcrumbs();

            // Install all of the plugins
            self._drainPlugins();

            self._isRavenInstalled = true;
        }

        Error.stackTraceLimit = self._globalOptions.stackTraceLimit;
        return this;
    },

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

image.png

参考文献:
GlobalEventHandlers.onerror
What the heck is "Script error"?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,047评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,494评论 18 139
  • 仍记得初中班主任在班上激慨地对我们说“不用羡慕谁,也不用嫉妒谁,你只要成为自己的那种人就可以了!”……这句话总是会...
    月島雯阅读 219评论 0 0
  • 走了那么久 是该继续嘻哈狡黠地讲讲孬话当作玩笑笑到肚疼心痛 还是选择沉默忘却周遭事物执著地继续爬行 越来越看不到最...
    加油艾特你阅读 304评论 0 0
  • 2017年给自己定下的目标之一是要做12本书的“强力读书笔记”——通过深入阅读后写出书的脉络、亮点、想法和联系。 ...
    吕星慧阅读 343评论 0 0