1. 程式人生 > >讀書筆記(04) - 錯誤監控 - JavaScript高級程序設計

讀書筆記(04) - 錯誤監控 - JavaScript高級程序設計

作者 event 報錯 服務器 port 註意 script rev -o

技術分享圖片

錯誤類型

  1. 即時運行錯誤 (代碼錯誤)

  2. 資源加載錯誤

常見的錯誤

1. 類型轉換錯誤

建議使用全等===操作符

2.數據類型錯誤

建議加強類型判斷

// 數組倒序
function reverseSort(value) {
    if (value instanceof Array) { 
        // 使用instanceof驗證數據類型 
        // (基礎類型用typeof, 引用類型用instanceof)
        value.sort();
        value.revere()
    }
}
3. 通信錯誤

url參數編碼錯誤造成,建議使用encodeURIComponent()

對url參數數據進行編碼

// 錯誤的url參數
// http://www.xxx.com/?redir=http://www.xxx.com?a=b&c=d

// 針對redir後面的參數字符串進行編碼

// 封裝一個處理方法(摘自書中代碼)
function addQueryStringArg(url, name, value) {
    if (url.indexOf(‘?‘) < 0) {
        url += ‘?‘;        
    } else {
        url += ‘&‘;
    }
    url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
    return url;
}

錯誤的捕獲方式

針對即時運行錯誤
  1. try-catch(代碼可疑區域可增加try-catch

  2. window.onerror (全局監控js錯誤異常)

1. try-catch
try {
    // 可能會導致錯誤的代碼
} catch (error) {
    // 錯誤發生時處理
    console.log(error.message);
} finally {
    // 一定會執行(無論是否發生錯誤)
}

TIPS: 使用了finallytrycatchreturn語句都會被忽略

function testFinally() {
    try {
        return 2;
    } catch (error) {
        return 1;
    } finally {
        return 0;
    }
}

// testFinally 最終返回 0

TIPS: try-catch只能捕獲同步運行的代碼錯誤,無法檢測語法和異步錯誤

(語法可借助ESlint工具在開發階段提示解決)

2. window.onerror

遵循DOM0級事件,window.onerror事件處理程序不會創建event對象,但可以接收三個參數message(錯誤信息), url(錯誤文件url), line(行號)

window.onerror = function(message, url, line){
    console.log(message, ulr, line);
};

在事件處理程序中返回false,可以阻止瀏覽器報告錯誤的默認行為

window.onerror = function(message, url, line) {
    return false;
}
針對資源加載錯誤
  1. object.onerror

  2. performance.getEntries()

  3. Error事件捕獲 (全局監控靜態資源異常)

1. object.onerror

如script,image等標簽src引用,會返回一個event對象

TIPS: object.onerror不會冒泡到window對象,所以window.onerror無法監控資源加載錯誤

var img = new Image();
img.src = ‘http://xxx.com/xxx.jpg‘;
img.onerror = function(event) {
    console.log(event);
}

技術分享圖片技術分享圖片

2. window.performance.getEntires()

適用高版本瀏覽器,返回已成功加載的資源列表,然後自行做比對差集運算,核實哪些文件沒有加載成功

var result = [];
window.performance.getEntries().forEach(function (perf) {
    result.push({
        ‘url‘: perf.name,
        ‘entryType‘: perf.entryType,
        ‘type‘: perf.initiatorType,
        ‘duration(ms)‘: perf.duration
    });
});
console.log(result);

技術分享圖片

3. Error事件捕獲
window.addEventListener(‘error‘, function(error){
    //...(全局監控靜態資源異常)
    console.log(error);
})

跨域的js錯誤捕獲

一般涉及跨域的js運行錯誤時會拋出錯誤提示script error,但沒有具體信息(如出錯文件,行列號提示等), 可利用資源共享策略來捕獲跨域js錯誤

  1. 客戶端:在script標簽增加crossorigin屬性(客戶端)

  2. 服務端:js資源響應頭Access-Control-Allow-Origin: *

錯誤上報

  1. Ajax請求 (會有跨域問題)

  2. 動態創建Image標簽 (兼容完美,代碼簡潔,需要註意瀏覽器url長度限制)

Image標簽
(new Image()).src= ‘http://xxx.com/error?code=1002‘
上報頻率

錯誤信息頻繁發送上報請求,會對後端服務器造成壓力。
項目中我們可通過設置采集率,或對規定時間內數據匯總再上報,減少請求數量,從而緩解服務端壓力。

// 借鑒別人的一個例子
Reporter.send=function(data) {
    // 只采集30%
    if(Math.random() < 0.3) {
        send(data); // 上報錯誤
    }
}

參考文檔

  • 《JavaScript高級程序設計》

  • 《如何優雅處理前端異常》

作者:以樂之名本文原創,有不當的地方歡迎指出。轉載請指明出處。

讀書筆記(04) - 錯誤監控 - JavaScript高級程序設計