QA不是萬能的,用戶的瀏覽環境非常復雜,很多情況無法靠測試用例去覆蓋,所以最好建立一個前端錯誤日志,在真實用戶端收集bug。
try&catch是一個捕獲前端錯誤的常見方法,比如:
{
//給所有腳本設置一個統一入口,比如設置一個init函數
init();
}catch(e){
//處理錯誤,將錯誤信息上報給服務器
}
像上面這樣,所有腳本統一用init作為入口,一旦發生錯誤就會被try捕獲,然后交給catch去處理。
這種做法雖然能夠收集錯誤信息,但弊端是必須統一一個腳本入口,並且把入口放在try里面,所以在實現時會比較麻煩。
理想情況下,處理錯誤信息的腳本應該盡可能做到無痕,為了實現這一點,可以借助window.onerror事件。
在W3C規范里,window.onerror是html5新定義的事件,但實際上,window.onerror從IE6開始就被支持了,而chrome、firefox、safari、opera,目前也都已經支持該事件。
// 基於window.onerror 收集前端錯誤信息
window.onerror = function(message, url, line) {
if (!url) return;
var msg = {};
//記錄客戶端環境
msg.ua = window.navigator.userAgent;
//只記錄message里的message屬性就好了,
//錯誤信息可能會比較晦澀,有些信息完全無用,應酌情過濾
msg.message = message.message;
msg.url = url;
msg.line = line;
msg.page = window.location.href;
var s = [];
//將錯誤信息轉換成字符串
for(var key in msg){
s.push(key + '=' + msg[key]);
}
s = s.join('&');
//這里是用增加標簽的方法調用日志收集接口,優點是比較簡潔。
new Image().src = '/ajax-jserror.php?' + encodeURIComponent(s) + '&t=' + Math.random();
};
這段代碼只要最好放到head標簽里,放在所有script之前,這樣當用戶瀏覽時發生的JS錯誤就會上報到服務器了。
這里有幾個點需要注意,一個是日志收集接口暴露在外,最好增加安全措施,比如設置token。
另外,腳本部署的時機、位置,以及日志過濾等條件,也需要根據具體情況進行設定。
onerror的事件綁定
如果想用事件綁定的方法處理window.onerror,有一點需要特別注意:
if(window.addEventListener){
/*
需要特別注意addEventListener的第三個參數,是否在捕獲階段處理
這個參數,大多數時候用的都是false
在這里,chrome、firefox也都可以用false
但是opera用false時就無法處理error
必須設置為true,在捕獲階段處理error,腳本才能正常運行
*/
window.addEventListener("error",fn,true);
}else if(window.attachEvent){
//ie在這里表示無壓力
window.attachEvent("onerror",fn);
}
