windows下面的全局error事件程序,當有javaSript腳本運行錯誤或者資源<img>、<script>加載失敗時,都會觸發Event接口的error事件,也能被window.addEventListener捕獲到
兩種寫法前端
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);
注意vue
這種方式應該是咱們平時用的最多的,具體功能想必你們也應該都很清楚,將咱們須要檢測的代碼包裹在try和catch中,當發生語法錯誤或者其餘錯誤時,就會從catch裏捕獲到,而無論前端發生了什麼,最後finally裏的代碼總會執行。
下面的代碼會怎麼執行,你們能夠思考一下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
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' });
咱們能夠經過下面的方法監聽到git
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(); });
可是這方法的兼容性有點失望github
‘Script error’ 這個錯誤是比較常見的,通常經過windows.onerror捕獲到後基本確實就是哪一個script文件有問題,並且這個文件仍是跨域的,既然是跨域致使信息不全,因此首先要解決的就是跨域問題,關於跨域方面的前端解決方案能夠看我這篇文章《 前端常見跨域方案彙總
)》;
對於script標籤,咱們還須要額外配置一個參數crossOriginweb
<script src='www.example.com' crossorigin></script>
至於服務端,經常使用的就是windows
對於這個功能的講解,看阮大神的 講解
)是最適合不過的了,固然瞭解其基本設計思路也是很重要的,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![]()
![]()