前端所有錯誤捕獲方法和上報方案

語言: CN / TW / HK

前端所有錯誤類型以及捕獲方式

JS Error

js 1. window.addEventListener('error',function(err){ console.log('事件捕獲...',err) },true) 2. window.onerror=function(err){ console.log('事件捕獲...',err) }

報錯信息:Script error .

當加載自不同域的腳本中發生語法錯誤時,瀏覽器為避免信息泄露的安全風險,語法錯誤的細節將不會報吿給瀏覽器console中,而是使用"Script error."信息代替。

一般而言,如果是第三方的JS資源,和頁面自身的URL產生了跨域問題,所以引起了"Script Error"。

解決方法:我們為 script 標籤添加 crossOrigin 屬性。 ```js

```

網絡請求的異常

由於網絡請求異常不會事件冒泡,就算在捕獲中無法判斷 HTTP 的狀態是 404 或是比如 500 等等,所以還需要配合服務端日誌才進行排查分析才可以。

所以我們一般配合一些請求庫去完成完成網絡請求異常的捕獲。比如axios進行回調捕獲,或者ajax回調捕獲,或是promise化catch。

Promise Catch

unhandledrejection 只能捕獲未顯式處理的Promise異常 ```js // 能觸發 unhandledrejection ,因為未顯式處理reason Promise.reject('error').then() Promise.reject('error').then(console.log)

// 不能觸發 unhandledrejection ,因為已處理reason Promise.reject('error').then(console.log, console.log) // 不能觸發 unhandledrejection ,因為沒處理reason,直接拋出異常 Promise.reject('error') 監聽捕獲方法js // 全局監聽 Uncaught Promise Error。 window.addEventListener("unhandledrejection", function(e){ // e.preventDefault(); // 阻止異常向上拋出 console.log('捕獲到異常:', e); }); window.onunhandledrejection = function(e){ // e.preventDefault(); // 阻止異常向上拋出到全局,不在console中顯示 console.log('捕獲到異常:', e); }; ```

常見框架處理

React錯誤處理 js componentDidCatch(error, info) { // Display fallback UI this.setState({ hasError: true }); // You can also log the error to an error reporting service logErrorToMyService(error, info); } Vue錯誤處理 js Vue.config.errorHandler = function (err, vm, info) { // vm為拋出異常的 Vue 實例 // info為 Vue 特定的錯誤信息,比如錯誤所在的生命週期鈎子 let { message, // 異常信息 name, // 異常名稱 script, // 異常腳本url line, // 異常行號 column, // 異常列號 stack // 異常堆棧信息 } = err; })

數據上報方式(可用於數據埋點)

關閉或者最小化瀏覽器時回調

  1. beforeunload (關閉前確認彈窗) 部分移動端不觸發
  2. unload 關閉時 部分移動端不觸發
  3. pagehide 隱藏時 部分移動端不觸發

延遲瀏覽器關閉或跳轉的方法:

用户場景:當用户導航到另一個頁面或者關閉頁面,希望關閉或跳轉前將數據完整發送

  1. 創建一個img元素並設置它的src。阻塞主線程,大多數瀏覽器會延遲卸載以加載圖像。
    • 在src中創建埋點url,服務端通過get方式接收
    • 原理:佔用瀏覽器主線程,大多數瀏覽器會延遲卸載以加載圖像。
  2. 創建幾秒鐘的無操作循環。 js let currTime=new Date().valueOf()) while(new Date()>currTime+3000){}
  3. 通過配置將XHR同步發送請求
    • axios默認是異步的,瀏覽器可能會過早關閉或跳轉導致取消發送
    • 通過配置將XHR改為同步發送請求,但是可能會影響用户跳轉的速度。
  4. sendBeaconAPI 64KB限制 IE兼容性問題 post請求
    • body大小64KB限制 IE兼容性問題 post請求
    • 瀏覽器將 Beacon 請求排隊讓它在空閒的時候執行
    • 瀏覽器進行了優化:可以將 Beacon 請求合併到其他請求上,一同處理, 尤其在移動環境下。
    • 異步發送 不阻塞進程