更多细节点击html
在前端开发工做中,除了项目开发保质保量上线之外,项目的数据监控也应该配套起来,确保线上的正常运转。如上报 pv监控项目是否正常运转;测速上报反应项目质量;脚本错误监控做为监控中重要一环,当页面发生报错的时候,经过上报错误信息,能及时发现存在问题,修复优化、减小损失。前端
脚本错误主要有两类:语法错误、运行时错误。监控的方式主要有两种:try-catch、window.onerror。git
try { test // <- throw error } catch(e){ console.log('运行时错误信息 ↙'); console.log(e); }
经过给代码块进行 try-catch 包装,当代码块出错时 catch 将能捕获到错误信息,页面也将继续执行。github
当发生语法错误或异步错误时,则没法正常捕捉。web
try { function empty() // <- throw error 语法错误 } catch(e){ console.log('语法错误信息 ↙'); console.log(e); }
没法捕捉错误跨域
语法错误没法在 try-catch 中进行捕抓、而异步报错则能够经过为异步函数块再包装一层 try-catch,增长标识信息来配合定位,能够用工具来进行处理,这里不展开。浏览器
/** * @param {String} msg 错误信息 * @param {String} url 出错文件 * @param {Number} row 行号 * @param {Number} col 列号 * @param {Object} error 错误详细信息 */ window.onerror = function (msg, url, row, col, error) { console.log('onerror 错误信息 ↙'); console.log({ msg, url, row, col, error }) }; test // <- throw error
window.onerror 能捕捉到当前页面的语法错误或运行时报错,是十分强大的。那么try-catch 是否再也不须要呢?其实并非。在使用过程当中的体会:onerror 主要用来捕获预料以外的错误,而 try-catch 则能够用在预知状况下监控特定错误,两种形式结合使用更加高效。缓存
监控错误拿到了报错信息,接下来则是将捕抓的错误信息发送到信息收集平台上,发送的形式主要有两种:安全
function report(msg, level) { var reportUrl = "http://localhost:8055/report"; new Image().src = reportUrl + '?msg=' + msg; }
监控报错,并将捕捉到的错误信息上报给数据收集平台,以下图服务器
有了监控了后,就能够在收集平台上进行查看脚本错误量的日志统计。
发现占据榜首的错误信息 “Script error.” 具备很是高的比例,没有无具体的错误信息,没法定位问题,而这是怎么产生的呢?
翻看在 webkit 的源码能够看到 “Script error.” 是浏览器在同源策略限制下所产生的。浏览器出于安全上的考虑,当页面引用的非同域的外部脚本中抛出了异常,此时本页面无权限得到这个异常详情, 将输出 Script error 的错误信息。
Script error 来自同源策略的影响,那么解决的方案之一是进行资源的同源化,另外也能够利用跨源资源共享机制( CORS )。
以上两种方式可以简单直接地解决问题,但也可能带来其余影响,如内联资源很差利用文件缓存,同域没法充分利用cdn优点等等。
跨源资源共享 ( CORS )机制让Web应用服务器能支持跨站访问控制,从而可以安全地跨站数据传输。主要是经过给请求带上特定头信息,服务器实现了CORS接口,就能够跨源通讯,从而可以看到具体报错信息。
<script src="http://127.0.0.1:8077/main.js" crossorigin></script>
增长 crossorigin 属性后,浏览器将自动在请求头中添加一个 Origin 字段,发起一个 跨来源资源共享 请求。Origin 向服务端代表了请求来源,服务端将根据来源判断是否正常响应。
Access-Control-Allow-Origin: * 表示经过该跨域请求,且该资源能够被任意站点跨站访问。而当该资源仅容许来自 http://127.0.0.1:8066 的跨站请求,其它站点都不能跨站访问时,将能够返回:
Access-Control-Allow-Origin:http://127.0.0.1:8066
Vary 字段的做用在于为缓存服务器提供缓存规则及缓存筛选的依据。当增长 Vary:Origin 响应头后,缓存服务器将会按照 Origin 字段的内容,缓存不一样版本,在请求响应时根据请求头中的 Origin 决定是否可以使用缓存响应。
举例 · 不加 Vary 将存在错误命中缓存的问题
上图中,第一个请求(Origin: 127.0.0.1:8066)响应被浏览器缓存了,当第二个请求(Origin: 127.0.0.1:8888)发起,被错误命中了前一个请求的缓存,收到了 Access-Control-Allow-Origin:http://127.0.0.1:8066 的响应时,将致使资源加载失败。因此当 Access-Control-Allow-Origin 不是返回为 * 时,须要加上 Vary 返回头来避免引缓存致使的权限问题。
跨域脚本报错产生 Script error. 经过以上方式进行处理后将可以捕获到具体的报错信息了。在 NodeJS 的实现中主要经过添加如下代码:
app.use(function *(next){ // 拿到请求头中的 Origin var requestOrigin = this.get('Origin'); if (!requestOrigin) { // 不存在则忽略 return yield next; } // 设置 Access-Control-Allow-Origin: Origin this.set('Access-Control-Allow-Origin', requestOrigin); // 设置 Vary: Origin this.vary('Origin'); return yield next; });