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

語言: 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 請求合併到其他請求上,一同處理, 尤其在移動環境下。
    • 非同步傳送 不阻塞程序