js異常監控上報

須要上報的錯誤類型:

  • 1.靜態資源加載失敗
  • 2.AJAX請求失敗
  • 3.js異常
    • 運行時錯誤
      • 同步錯誤
      • 異步錯誤
    • 語法錯誤
  • 4.promise異常

異常捕獲方法

1.try catch

  • 注意:只能捕獲同步運行時的錯誤,不能捕獲語法錯誤和異步錯誤。
    • 捕獲運行時同步錯誤
      try{
              var a = 1;
              var c = a + b;
              console.log(c)
          }catch(e){
              console.log(e)  //ReferenceError: b is not defined
          }
      複製代碼
  • 使用try catch可以很好的捕獲異常並對應進行相應處理,不至於讓頁面掛掉,可是其存在一些弊端,好比須要在捕獲異常的代碼上進行包裹,會致使頁面臃腫不堪,不適用於整個項目的異常捕獲。

2.window.onerror

  • 相比try catch來講window.onerror提供了全局監聽異常的功能:
window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error){
        console.log('errorMessage: ' + errorMessage); // 異常信息
        console.log('scriptURI: ' + scriptURI); // 異常文件路徑
        console.log('lineNo: ' + lineNo); // 異常行號
        console.log('columnNo: ' + columnNo); // 異常列號
        console.log('error: ' + error); // 異常堆棧信息
    };

    console.log(a);
複製代碼

結果以下: javascript

avatar
window.onerror即提供了咱們錯誤的信息,還提供了錯誤行列號,能夠精準的進行定位

  • 注意:window.onerror 對於靜態資源異常,接口異常,都捕獲不到。html

    • 試下捕獲異步
    window.onerror = function(messsage, source, lineno, colno, error){
            console.log('捕獲到異常:',{
                messsage, source, lineno, colno, error
            })
        }
        setTimeout(function(){
            undefined.map(v=>v)
        },1000)
    複製代碼

    輸出: java

    avatar

  • 注意:onerror 最好寫在全部 JS 腳本的前面,不然有可能捕獲不到錯誤;webpack

3.使用window.addEventListener 解決捕獲靜態資源問題:

  • 當一項資源(如圖片或腳本)加載失敗,加載資源的元素會觸發一個 Event 接口的 error 事件,並執行該元素上的onerror() 處理函數。這些 error 事件不會向上冒泡到 window ,不過(至少在 Firefox 中)能被單一的window.addEventListener 捕獲。
<script> window.addEventListener('error',error=>{ console.log('捕獲到異常:',error) },true) </script>
    <img src="./xxx/png" />
複製代碼
  • 因爲網絡請求異常不會事件冒泡,所以必須在捕獲階段將其捕捉到才行,可是這種方式雖然能夠捕捉到網絡請求的異常,可是沒法判斷 HTTP 的狀態是 404 仍是其餘好比 500 等等,因此還須要配合服務端日誌才進行排查分析才能夠。web

  • 注意:不一樣瀏覽器下返回的 error 對象可能不一樣,須要注意兼容處理。須要注意避免 addEventListener 重複監聽。ajax

異常捕獲問題

跨域問題

<script src="http://cdn.xxx.com/index.js"></script>
複製代碼

如今把js文件放到跨域的cdn上面,運行訪問:http://localhost/8000以下:跨域

avatar
通過分析發現,跨域以後window.onerror是沒法捕獲異常信息的,因此統一返回Script error.,解決方案即是script屬性配置 crossorigin=」anonymous」 而且服務器添加Access-Control-Allow-Origin。

<script src="http://cdn.xxx.com/index.js" crossorigin="anonymous"></script>
複製代碼

加上crossorigin=」anonymous」後如圖: promise

avatar

2. sourceMap

解決跨域或者將腳本存放在同域以後,你可能會將代碼壓縮一下再發布,這時候便出現了壓縮後的代碼沒法找到原始報錯位置的問題。如圖,咱們用webpack將代碼打包壓縮成bundle.js: 瀏覽器

avatar

解決辦法:在webpack配置中加入devtool: '#source-map'。服務器

錯誤上報

經過ajax 發送數據

  • 由於 Ajax 請求自己也有可能會發生異常,並且有可能會引起跨域問題,通常狀況下更推薦使用動態建立 img 標籤的形式進行上報

動態建立 img 標籤的形式

function report(error) {
        let reportUrl = 'http://jartto.wang/report';
        new Image().src = `${reportUrl}?logs=${error}`;
    }
複製代碼

總結

  • 1.可疑區域增長 Try-Catch
  • 2.全局監控 JS 異常 window.onerror
  • 3.全局監控靜態資源異常 window.addEventListener
  • 4.捕獲沒有 Catch 的 Promise 異常:unhandledrejection
  • 5.VUE errorHandler 和 React componentDidCatch
  • 6.監控網頁崩潰:window 對象的 load 和 beforeunload
  • 7.跨域 crossOrigin 解決
相關文章
相關標籤/搜索