内容简介:从自测到QA测试以及上线前的Code Review ,进过层层检查,还是会有疏忽。代码上线后,我们更多的是通过用户反馈或者后台的数据统计、异常数据来分析,找问题、定位问题。那么前端是否也能弄用一套比较完善的代码异步监控?例子错误:在某些情况下,上诉的src可能是null,导致这里调用null的indexOf方法发生异常。导致代码不往下走了。
从自测到QA测试以及上线前的Code Review ,进过层层检查,还是会有疏忽。代码上线后,我们更多的是通过用户反馈或者后台的数据统计、异常数据来分析,找问题、定位问题。那么前端是否也能弄用一套比较完善的代码异步监控?
例子错误:
src = img.getAttribute("src"); src.indexOf("http://XXX.com/"); 复制代码
在某些情况下,上诉的src可能是null,导致这里调用null的indexOf方法发生异常。导致代码不往下走了。
正常情况下,前端页面的语法错误以及运行时错误,都会在浏览器的console里边体现出来,包含错误的文件、行号、堆栈信息等。 那么有什么方法可以抓到错误日志?有两个方案:
-
try...catch(e)
针对某个代码块使用try...catch(e) 包装,这样错误就能被捕获到。缺点:
- 捕获不了异步错误(所以很多node,走的是回调的形式)
- 捕获不了全局错误事件
// demo2 可以捕获 try{ var i = 0; console.log(I) var c = b + cc }catch(e){ console.log(e) } // demo3 无法捕获 try{ setTimeout(()=>{ var i = 0; console.log(I) var c = b + cc }, 0) }catch(e){ console.log(e) } 复制代码
- window.onerror
window.onerror 可以拿到出错信息的文件名、行号、列号,还可以在window.onerror最后return true让浏览器不输出错误信息到控制台。 注意:
- window.onerror 代码块需要独立出去,避免与业务代码块、语法错误的代码块一起,避免事件不生效。
-
对于跨域的JS 资源,window.onerror 也无法监听到。
- js 处加上 crossorigin
- 加上 Access-Control-Allow-Origin
因此通常路径是监听全局的window.onerror 事件捕获到运行时的错误,然后上报到采集端,最后再做一个页面展示数据。
利用new Image 的方式采集日志
window.onerror = function (msg, url, line, col, error) { // 最后实时过滤出日志 (new Image).src = `/data?msg=${msg}&url=${url}&line=${line}&col=${col}&error=${error}` console.log(msg) console.log(url) console.log(line) console.log(col) console.log(error) // return true 实现错误日志不输出到console 处 return true } 复制代码
最终形式:
window.onerror = function(msg,url,line,col,error){ //没有URL不上报!上报也不知道错误 if (msg != "Script error." && !url){ return true; } //采用异步的方式 //我遇到过在window.onunload进行ajax的堵塞上报 //由于客户端强制关闭webview导致这次堵塞上报有Network Error //我猜测这里window.onerror的执行流在关闭前是必然执行的 //而离开文章之后的上报对于业务来说是可丢失的 //所以我把这里的执行流放到异步事件去执行 //脚本的异常数降低了10倍 setTimeout(function(){ var data = {}; //不一定所有浏览器都支持col参数 col = col || (window.event && window.event.errorCharacter) || 0; data.url = url; data.line = line; data.col = col; if (!!error && !!error.stack){ //如果浏览器有堆栈信息 //直接使用 data.msg = error.stack.toString(); }else if (!!arguments.callee){ //尝试通过callee拿堆栈信息 var ext = []; var f = arguments.callee.caller, c = 3; //这里只拿三层堆栈信息 while (f && (--c>0)) { ext.push(f.toString()); if (f === f.caller) { break;//如果有环 } f = f.caller; } ext = ext.join(","); data.msg = ext; } //把data上报到后台! },0); return true; }; 复制代码
前端日志存储,通常不会去实时上传日志,而是先存储,比如: Cookie, localStorage, sessionStorage, IndexDB, webSQL, FileSystem 几种毕竟方式
存储方式 | cookie | localStorage | sessionStorage | IndexDB | webSQL |
---|---|---|---|---|---|
容量 | 4K | 5M | 5M | 500M | 60M |
进程 | 同步 | 同步 | 同步 | 异步 | 异步 |
检索 | key | key | key | key, index | field |
IndexedDB是最好的选择,它具有容量大、异步的优势,异步的特性保证它不会对界面的渲染产生阻塞。而且IndexedDB是分库的,每个库又分store,还能按照索引进行查询,具有完整的数据库管理思维,比localStorage更适合做结构化数据管理。但是它有一个缺点,就是api非常复杂,不像localStorage那么简单直接。针对这一点,我们可以使用hello-indexeddb这个工具,它用Promise对复杂api进行来封装,简化操作,使IndexedDB的使用也能做到localStorage一样便捷
框架层异常处理
vue 中的 Vue.config.errorHandler
, React 有ErrorBoundary 。
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } componentDidCatch(error, info) { this.setState({ hasError: true }); // 在这里可以做异常的上报 logErrorToMyService(error, info); } render() { if (this.state.hasError) { return <h1>Something went wrong.</h1>; } return this.props.children; } } // 在使用时,用 ErrorBoundary 包裹你的业务组件即可: <ErrorBoundary> <MyWidget /> </ErrorBoundary> 复制代码
window.performance 有浏览器相关时间的api
监听hash change 变化上报pv
以上所述就是小编给大家介绍的《前端监控了解与简易实现》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
乔布斯离开了,马斯克来了
[日]竹内一正 / 干太阳 / 中信出版社 / 2015-11
在电动汽车的创新上,特斯拉抓住了一个群体的独特需求,外形很酷,不烧油,智能化控制。所有的颠覆式创新都不是敲锣打鼓来的,而是隐藏在一片噪声里,马斯克给我们带来的特斯拉虽然不尽完美,但他做产品的思维和执着于未来的勇气,值得学习。埃隆•马斯克创办公司也不是为了赚钱,而是为了拯救人类和地球,电动汽车、太阳能发电、宇宙火箭,不管是哪一项都足以令一个国家付出巨大的代价去研究开发,但埃隆•马斯克却一个人在做这些......一起来看看 《乔布斯离开了,马斯克来了》 这本书的介绍吧!
JS 压缩/解压工具
在线压缩/解压 JS 代码
图片转BASE64编码
在线图片转Base64编码工具