zoukankan      html  css  js  c++  java
  • 前端异常采集

    为什么要做前端代码异常采集?好问题!
    为了用户能安心用产品,不至于时不时“卡壳”崩溃。
    为了能高效定位线上代码的异常并提供简单提示信息。
    为了程序猿同胞们能睡个好觉。

    本文完整示例请移步github:FEerrorLog

    捕获异常的方法

    js捕获异常的方法,两三个而已。

    1. try...catch 优缺点已有很多论述和解决方案,本文的异常采集并未建立在该方法之上,只是少量使用。
    2. window.onerror和方法3类似但不如方法3强大,因此未选用此方法。
    3. window.addEventListener('error',function(){},true),采用此方法。

    前端异常包含两部分:
    第一部分:window.onerror()能捕获到的异常,当然如果用addEventListener无论冒泡还是捕获阶段也能捕获到该异常。
    第二部分:资源加载失败,即<img><script>标签上的onerror,这个异常无法通过冒泡到达window,但是可以在捕获阶段拿到,这就是为什么要将addEventListener第三个参数置成true了。

    注意:为保证该异常采集脚本能执行到,不被先行执行的脚本里面的报错阻断,该脚本要放到最前面。

    可能的异常及采集方案

    1. 资源加载失败,样式、图片、脚本文件的请求异常,比如js加载404了
    2. js脚本异常,即控制台常见的Error信息
    3. 检测HTML劫持,比如被运营商强行注入标签或脚本
    4. 页面样式丢失,CSS 展现异常

    1. 资源加载失败

    http异常用js几乎抓不到有用异常信息,但是404异常可以进行简单处理,此时是不会执行onerror的回调函数的。因为在addEventListener捕获到的异常信息中你可以发现,对应于onerror的五个回调参数根本不存在了,但是addEventListener中除这五个外,还有其他可以用的key,如果想获取加载失败的资源是哪个,可以去target中找些有用信息,我使用的是e.target.outerHTML

    "HttpError at " + (e.target.baseURI || location.href) + " outerHTML:" + e.target.outerHTML
    

    2. js异常

    一般需要采集的信息:

    1. 异常的提示信息,会直接告诉你是什么异常。这是识别一个异常的最重要依据,即e.message中的信息。
    2. JS 文件名:异常发生在那个文件中。是堆栈信息中最顶层的那个文件。即e.filename。
    3. 异常所在行、列:异常的具体位置。行信息各浏览器基本还是一致的,列信息的差别较大,仅供参考。
    4. 堆栈信息:异常信息发生的堆栈,也是函数调用的堆栈信息,每下一层都是上一层的运行环境。即e.error.stack。每一层都包含类型、文件、行、列信息。但是注意堆栈信息可能会比较多,可以根据需要截取上报。safari和firfox的e.error.stack中不包含以上1,2,3的信息,只有堆栈信息,而chrome和IE中都包含,此处需要做兼容处理。
    5. 发生异常的设备信息,可以从window.navigator中选取自己需要的信息,或者直接使用window.navigator.userAgent
    6. 发生异常的时间点,不多说。

    js主动抛出异常
    js异常除了可以是系统抛出的几类异常,还可以是开发者利用throw关键字主动抛出异常。
    值:可以是字符串、数字逻辑值或对象
    使用方式:

    //利用Error对象或其实例,采集到的异常系统自动为其添加了堆栈信息,和系统抛出异常基本类似
    throw new Error('Problem description.')
    throw Error('Problem description.') 
    //直接利用关键字抛出内容,会完全复写event.error的内容,不推荐使用。
    throw 'Problem description.' 
    throw null 
    

    另外:
    console.error()和throw new Error()抛出的错误信息是有本质区别的。前者不会阻断js运行,也不会被error事件捕捉到,只是在控制台打印错误信息。

    以下方式可以阻止异常信息在控制台中显示,线上可以自行收集异常信息后阻止外人看到控制台报错,开发环境不建议使用。

        window.addEventListener('error', (function(e) {
            console.log("-----errorEvent----", e)
            e.preventDefault()  //这里换成 return false或return true均不行!
        }), true);
        
        window.onerror = function(msg, url, line, col, error) {
            console.log("------errorInfo---",msg, url, line, col, error)
            return true;   //这里用return false不行!
        }
    

    3. 检测html劫持

    我选用的方案是保存真实环境中的html信息,并对比原html,检测是否有被篡改。
    采集html文档用到的是document.documentElement.outerHTML。但是有一点需要注意,上面已提到,该文件需要放在最前面,所以直接用该方法拿到的可能只有<head>中的html。因此如果想拿到完整的页面信息,需要将采集时间点放到onload以后。

        //所有io操作最好都try...catch一下,这里是防止储存的信息超过localStorage的最大限制。关于最大限制是多少已经有不少人说过了,大家可以选择性看一些,如果有必要可以亲测一下。
        window.addEventListener("load", function() {
            try {
                localStorage.setItem("hawkeyeHtml", document.documentElement.outerHTML);
            } catch (e) {
                //超过限度时,chrome和safari的e.name为'QuotaExceededError',FF的e.name为'NS_ERROR_DOM_QUOTA_REACHED'
                console.error(e)
            }
        })
    

    4. 页面样式丢失

    尚未做此数据采集和监控,目前考虑大体思路和html劫持类似,保存截屏图片,用一定算法和正常样式下做对比,超过一定差异值即判定为样式异常。

    数据处理方式:

    1. 上报监控服务器:便于统一监控异常数量类型等
      方案:我司仍选择img的属性src进行上报,一是考虑到解析性能,二是考虑到要为多站点服务,方便跨域上报。
    2. html页面打印前端异常:便于快速准确定位某使用环境崩溃原因
      方案:采集到信息储存在localstorage中,注意控制储存的条数。在需要查看异常信息的网站中增加该页面,取出进行简单处理即可。

    缺陷处理

    1. 线上代码是混淆压缩的,无行号
      解决方案:线上也用sourceMap来解决,至于sourMap是什么,怎么使用,根据项目不同,可自行google。
    2. 跨域的js,异常信息只有一个"Script error"。虽然js拿不到任何其他异常信息,但是控制台能打印出全部异常信息。所以
      解决方案一:匹配到"Script error",引导开者去控制台查看或直接过滤掉。
      解决方案二:解决跨域问题,分两步。一:静态资源请求需要加多一个Access-Control-Allow-Origin头部。二:<scrip>标签加上crossorigin属性
    3. 跨域的js,获取不到js文件名,会拿到at <anonymous>:1:1酱紫的信息,暂时没找到解决方案

    推荐文章:JavaScript Errors Handbook:里面有部分内容已不适用,具体实施请注意验证

  • 相关阅读:
    mybatis逆向工程
    fastdfs搭建和使用
    solr学习笔记
    自己搭建anki服务器
    redis总结
    java基础——队列
    遍历文件夹下的文件,并且获取文件名字
    xls到xml
    xls文件导入数据库
    PyCharm怎样添加Qt designer
  • 原文地址:https://www.cnblogs.com/bldxh/p/6923370.html
Copyright © 2011-2022 走看看