提及埋點又到了談起前端項目中數據收集與監控,那麼今天來簡單的聊下前端報錯監控的埋點。前端
首先先安利下本身作的報錯監控的項目 FE-Monitor 歡迎 issue 和 star 。jquery
首先咱們能夠看下前端作報錯監控的意義在哪裏:git
整體來講前端監控的主要目的都是爲了獲取用戶行爲以及跟蹤產品在用戶端的使用狀況,並以監控數據爲基礎,指明產品優化方向。github
try {
test code // throw error
} catch(e){
console.log(e);
}
複製代碼
上面的代碼在項目中很常見,通常用來捕獲某一段可能代碼拋出的錯誤信息。而且在try catch 中的錯誤並不會阻塞整個頁面,即便發生錯誤,頁面也能夠繼續執行。ajax
固然,咱們不太可能對這個項目中的每一段代碼都添加 try catch,這樣不只不利於線上定位問題產生的緣由,也會讓代碼難以維護,目前主流的就是在項目中獨立引入一個報錯監控的 JS 來單獨的完成對整個項目的監控。函數
好比 FE-Monitor 就提供開源的項目報錯監控的能力,只須要將 SDK 引入本身的項目中,便可監控整個項目的js執行報錯,資源加載異常,ajax錯誤等信息了。測試
ajax 的錯誤監控主要是爲了發現服務接口返回值的問題。優化
看了一些產品的實現都是對 window 下的 XMLHttpRequest
重寫,可是這樣直接重寫不只會形成調用鏈的修改也會讓宿主頁面上的多個 ajax 庫產生衝突,如使用了 jquery 的話 jquery 中是直接使用 XMLHttpRequest
對象的。若是修改了全局的對象中的屬性可能會形成之外的影響。ui
用了一種特殊的方式去實現對 XMLHttpRequest
對象的監聽。this
_initListenAjax: function () {
let self = this;
function ajaxEventTrigger(event) {
var ajaxEvent = new CustomEvent(event, { detail: this });
window.dispatchEvent(ajaxEvent);
}
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener('load', function ($event) {
ajaxEventTrigger.call(this, 'ajaxLoad');
}, false);
realXHR.addEventListener('timeout', function () {
ajaxEventTrigger.call(this, 'ajaxTimeout');
}, false);
realXHR.addEventListener('readystatechange', function() {
ajaxEventTrigger.call(this, 'ajaxReadyStateChange');
}, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
self._startLintenAjax();
}
複製代碼
這樣作不只能夠一經調用就監控到頁面的錯誤,不會出現重寫 window.onerror
的時候第一次錯誤監控不到的狀況還須要重寫 console.error
函數才能夠監聽到。
錯誤監控中對 error
事件的監控是最重要的,監聽 error 的事件主要是爲了發現 js 執行中拋錯。
window.addEventListener("error", function(err) {
getError(err, self._config);
}, true);
複製代碼
監控 error 報錯的狀況中,最 error 的處理中要判斷是不是咱們設置的埋點接口的 URL 所拋錯的。主要是爲了不在埋點服務宕機的狀況下出現重複請求上報,形成頁面卡死的狀況。
頁面上有不少的外部的資源,通常來講對資源的加載的監控是在資源標籤添加 onerror
的方法來監聽加載錯誤信息。
這種作法和對js 代碼添加 try catch同樣,須要對每一個資源都不斷的添加監控。
對比以後 使用 addEventListener
監控總體的項目資源加載更方便快捷。
window.addEventListener("error", function(err) {
getError(err, self._config);
}, true);
複製代碼
其中 addEventListener
方法中的第三個參數是 useCapture,若是將 useCapture 設置爲 true,則偵聽器只在捕獲階段處理事件,而不在目標或冒泡階段處理事件。 若是useCapture 爲 false,則偵聽器只在目標或冒泡階段處理事件。
其中回調函數中接受的 err 中有 cancelable
屬性的是js執行錯誤,因此能夠經過 err 上時候有 cancelable
屬性來判斷不一樣類型的錯誤。