windows下面的全局error事件程序,當有javaSript腳本運行錯誤或者資源<img>、<script>加載失敗時,都會觸發Event接口的error事件,也能被window.addEventListener捕獲到javascript
兩種寫法html
window.onerror = function(message, source, lineno, colno, error) {
console.log(message)//字符串錯誤信息
console.log(source)//發生錯誤的腳本
console.log(lineno)//發生錯誤的行號
console.log(colno)//發生錯誤的列號
console.log(error)//Erroe對象
return true//將代碼錯誤定格在捕獲階段
}
window.addEventListener('error', (msg, url, row, col, error) => {
console.log(
msg, url, row, col, error
);
return true;
}, true);
複製代碼
注意前端
這種方式應該是咱們平時用的最多的,具體功能想必你們也應該都很清楚,將咱們須要檢測的代碼包裹在try和catch中,當發生語法錯誤或者其餘錯誤時,就會從catch裏捕獲到,而無論前端發生了什麼,最後finally裏的代碼總會執行。vue
下面的代碼會怎麼執行,你們能夠思考一下java
try {
try {
throw new Error("oops");
}
catch (ex) {
console.error("inner", ex.message);
throw ex;
}
finally {
console.log("finally");
return;
}
}
catch (ex) {
console.error("outer", ex.message);
}
複製代碼
特別注意react
有些錯誤try..catch和windows.onerror也是無能爲力的,好比說Promise實例從pending轉變爲rejected時,若是加了catch就會被捕獲到,但要是沒有加,那麼繼續拋出就會
Uncaught(in promise) Error
webpack
好比下面代碼就捕獲不到錯誤git
window.onerror = function(message, source, lineno, colno, error) {
console.log(message)//字符串錯誤信息
console.log(source)//發生錯誤的腳本
console.log(lineno)//發生錯誤的行號
console.log(colno)//發生錯誤的列號
console.log(error)//Erroe對象
return true//將代碼錯誤定格在捕獲階段
}
// 調用Promise.reject類方法
Promise.reject('promise error');
// 在工廠方法中調用reject方法
new Promise((resolve, reject) => {
reject('promise error');
});
// 在工廠方法或then回調函數中拋異常
new Promise((resolve) => {
resolve();
}).then(() => {
throw 'promise error'
});
複製代碼
咱們能夠經過下面的方法監聽到github
window.addEventListener('unhandledrejection', function (event) {
// ...your code here to handle the unhandled rejection...
// Prevent the default handling (such as outputting the
// error to the console
event.preventDefault();
});
複製代碼
可是這方法的兼容性有點失望 web
‘Script error’ 這個錯誤是比較常見的,通常經過windows.onerror捕獲到後基本確實就是哪一個script文件有問題,並且這個文件仍是跨域的,既然是跨域致使信息不全,因此首先要解決的就是跨域問題,關於跨域方面的前端解決方案能夠看我這篇文章《前端常見跨域方案彙總》;
對於script標籤,咱們還須要額外配置一個參數crossOrigin
<script src='www.example.com' crossorigin></script>
複製代碼
至於服務端,經常使用的就是
對於這個功能的講解,看阮大神的講解是最適合不過的了,固然瞭解其基本設計思路也是很重要的,SourceMap其實就是一個信息文件,存儲着源文件的信息及源文件與處理後文件的映射關係。咱們平時vue或者react項目開發中,經過webpack配置在測試環境中默認開啓生成SourceMap,出現錯誤可以及時重現原代碼,可是正式環境咱們通常是不會將SourceMap文件發佈上去的,可是正式環境的代碼通常都是壓縮過的,因此若是報錯了,通常是很難 定位到原代碼的位置,這時候優秀的錯誤上傳功能,以及平臺處理錯誤分析就顯得尤其重要了。下圖就是大概的設計思路。
平時咱們很常見網頁卡頓或者直接崩潰,通常是經過window 對象的 load 和 beforeunload 事件實現了網頁崩潰的監控;具體看這篇文章,Logging Information on Browser Crashes
實現代碼
window.addEventListener('load', function () {
sessionStorage.setItem('good_exit', 'pending');
setInterval(function () {
sessionStorage.setItem('time_before_crash', new Date().toString());
}, 1000);
});
window.addEventListener('beforeunload', function () {
sessionStorage.setItem('good_exit', 'true');
});
if(sessionStorage.getItem('good_exit') &&
sessionStorage.getItem('good_exit') !== 'true') {
/*
insert crash logging code here
*/
alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash'));
}
複製代碼
可是上面的編碼模式存在不友好的問題,當咱們嘗試在卸載頁面前經過上傳服務器數據,爲了延遲頁面卸載,須要經過同步XMLHttpRequest 發送數據或者建立一個幾秒的循環來延遲卸載。這樣的處理可想而知不是很友好,這時候sendBeacon()就橫空出世了,很簡單的實現向服務器發送數據,同時又不會影響下一個頁面的加載,具體以下面簡單的代碼實現。
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon("www.youAddress.com", analyticsData);
}
複製代碼
成熟解決方案 badjs、 sentry、raven-js FunDebug
若是大神您想繼續探討或者學習更多知識,歡迎加入QQ或者微信一塊兒探討:854280588
![]()
![]()