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);
}