前端錯誤監控

爲何要作前端錯誤監控?

1. 爲了保證產品的質量前端

2. 有些問題只存在於線上特定的環境web

3. 後端錯誤有監控,前端錯誤沒有監控後端

前端錯誤的分類

前端錯誤分爲兩類: 即時運行錯誤資源加載錯誤跨域

即便運行錯誤的捕獲方式

即時運行錯誤的捕獲方式分爲兩類數組

  1. try...catch
  2. window.onerror

try...catch

經過try...catch咱們可以知道出錯的信息,而且也有堆棧信息能夠知道在哪一個文件第幾行第幾列發生錯誤瀏覽器

try {
           // 代碼段
        } catch (err) {
            console.log(err.message)
        }

缺點:服務器

  1. 無法捕捉try,catch塊,當前代碼塊有語法錯誤,JS解釋器壓根都不會執行當前這個代碼塊,因此也就沒辦法被catch住;
  2. 無法捕捉到全局的錯誤事件,也便是隻有try,catch的塊裏邊運行出錯纔會被你捕捉到,這裏的塊你要理解成一個函數塊

關於第一個缺點,咱們沒有任何解決辦法,可是通常語法階段咱們是能在開發階段/或者用工具檢測到的,因而乎它就被忽略了異步

第二個缺點應該怎麼理解呢? try...catch只能捕捉到當前執行流裏邊的運行錯誤,對於異步回調來講,是不屬於這個try...catch塊的函數

window.onerror

全局捕獲。window.onerror同樣能夠拿到出錯的信息以及文件名、行號、列號等信息,還能夠在window.onerror最後return true讓瀏覽器不輸出錯誤信息到控制檯工具

/*
         * @param msg{String}:錯誤消息
         * @param url{String}:引起錯誤的腳本的URL
         * @param line{Number}:發生錯誤的代碼行
         * @param colunm{Number}:發生錯誤的代碼列
         * @param error{object}:錯誤對象
         */

        window.onerror = function (msg, url, line, colunm, error) {
            // 返回 true 則錯誤消息不顯示在控制檯,返回 false,則錯誤消息將會展現在控制檯
            return true;
        }

最後window.onerror的實現方法

window.onerror = function (msg, url, line, col, error) {
            //沒有URL不上報!上報也不知道錯誤
            if (msg != "Script error." && !url) {
                return true;
            }
            
            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上報到後臺!
                console.log(data)
            }, 0);
            
            return true;
        };

資源加載錯誤

object.onerror

img、script標籤均可以添加onerror事件,當資源請求失敗的時候,都會觸發該事件

 var img = document.getElementById('img');
        img.onerror=function(){
            console.log("出錯啦");
        }

 

performance.getEntries()

performance是h5的新特性之一,使用該方法能獲取到當前頁面已經加載到的資源,返回的是一個數組對象。下面給出一個例子

獲取頁面中沒有成功加載的圖片資源?

步驟一:經過performance.getEntries()獲取已經加載了的圖片資源

let arr = [],
            reg = (/\.jpg$|\.jpeg$|.png$|\.gif$/i);
        performance.getEntries().forEach(item => {
            if (reg.test(item.name)) {
               arr.push(item.name)
            }
        })

步驟二:獲取頁面中全部的img標籤

let imgList=document.getElementByTagname('img')

步驟三:利用獲取到的img的長度減去已經加載到的長度,若是大於0的部分,就是加載失敗的

let arr = [],
        imgList=null,
        num=0,
            reg = (/\.jpg$|\.jpeg$|.png$|\.gif$/i);
        performance.getEntries().forEach(item => {
            if (reg.test(item.name)) {
               arr.push(item.name)
            }
        })
        imgList=document.getElementsByTagName('img');
        num=imgList.length-arr.length;

Error事件捕獲

資源加載錯誤,雖然會阻止冒泡,可是不會阻止捕獲。true:捕獲,false:冒泡

// window.addEventListener第三個參數是true的時候是捕獲的過程,false是冒泡的過程 
window.addEventListener('error',function(e){
        console.log("捕獲",e)
    },true)

 

跨域的JS文件異常捕獲

爲了提高web性能,大部分web產品都有CDN部署,將資源部署到不一樣的域名上,可是咱們都知道瀏覽器是有同源策略的,當加載不一樣域名的腳本發生錯誤時,語法錯誤的細節不會報告,僅返回"Script error",針對這種問題,能夠在服務器上設置"Access-Control-Allow-Origin:*",在請求資源的script標籤上加上crossorigin屬性便可

 <script src="xxxx/js/store.js" crossorigin></script>
相關文章
相關標籤/搜索