新聞中心
隨著前端頁面承載功能越來越多,用戶本地瀏覽器環(huán)境也錯綜復雜,因此即使有完善的測試,我們也無法保證上線的代碼不會出錯。在這種場景下,前端頁面的監(jiān)控就成了各個web項目必備的工具。

一般對頁面的監(jiān)控包含頁面性能、頁面錯誤以及用戶行為路徑獲取上報等。
而本文將重點關注其中的錯誤部分,主要介紹一下常見的錯誤類型以及如何對它們進行捕獲并上報。
常見錯誤的分類
對于用戶在訪問頁面時發(fā)生的錯誤,主要包括以下幾個類型:
1、js運行時錯誤
JavaScript代碼在用戶瀏覽器中執(zhí)行時,由于一些邊界情況、本地環(huán)境的不可控等因素,可能會存在js運行時錯誤。
而依賴客戶端的某些方法,由于兼容性或者網(wǎng)絡等問題,也有概率會出現(xiàn)運行時錯誤。
e.g: 下圖是當使用了未定義的變量"foo",導致產生js運行時錯誤時的上報數(shù)據(jù):
2、資源加載錯誤
這里的靜態(tài)資源包括js、css以及image等?,F(xiàn)在的web項目,往往依賴了大量的靜態(tài)資源,而且一般也會有cdn存在。
如果某個節(jié)點出現(xiàn)問題導致某個靜態(tài)資源無法訪問,就需要能夠捕獲這種異常并進行上報,方便***時間解決問題。
e.g: 下圖是圖片資源不存在時的上報數(shù)據(jù):
3、未處理的promise錯誤
未使用catch捕獲的promise錯誤,往往都會存在比較大的風險。而編碼時有可能覆蓋的不夠全面,因此有必要監(jiān)控未處理的promise錯誤并進行上報。
e.g: 下圖是promise請求接口發(fā)生錯誤后,未進行catch時的上報數(shù)據(jù):
4、異步請求錯誤(fetch與xhr)
異步錯誤的捕獲分為兩個部分:一個是傳統(tǒng)的XMLHttpRequest,另一個是使用fetch api。
像axios和jQuery等庫就是在xhr上的封裝,而有些情況也可能會使用原生的fetch,因此對這兩種情況都要進行捕獲。
e.g: 下圖是xhr請求接口返回400時捕獲后的上報數(shù)據(jù):
各個類型錯誤的捕獲方式
1、window.onerror與window.addEventListener('error')捕獲js運行時錯誤
使用window.onerror和window.addEventListener('error')都能捕獲,但是window.onerror含有詳細的error堆棧信息,存在error.stack中,所以我們選擇使用onerror的方式對js運行時錯誤進行捕獲。
- window.onerror = function (msg, url, lineNo, columnNo, error) {
- // 處理錯誤信息
- }
- // demo
- msg: Uncaught TypeError: Uncaught ReferenceError: a is not defined
- error.statck: TypeError: ReferenceError: a is not defined at http://xxxx.js:1:13
- window.addEventListener('error', event => (){
- // 處理錯誤信息
- }, false);
- // true代表在捕獲階段調用,false代表在冒泡階段捕獲。使用true或false都可以,默認為false
2、資源加載錯誤使用addEventListener去監(jiān)聽error事件捕獲
實現(xiàn)原理:當一項資源(如或
此步驟的作用是告知瀏覽器以匿名方式獲取目標腳本。這意味著請求腳本時不會向服務端發(fā)送潛在的用戶身份信息(例如 Cookies、HTTP 證書等)。
添加跨域 HTTP 響應頭:
- Access-Control-Allow-Origin: *
或者
- Access-Control-Allow-Origin: http://test.com
注意:大部分主流 CDN 默認添加了 Access-Control-Allow-Origin 屬性。
完成上述兩步之后,即可通過 window.onerror 捕獲跨域腳本的報錯信息。
解決方案2
難以在 HTTP 請求響應頭中添加跨域屬性時,還可以考慮 try catch 這個備選方案。
在如下示例 HTML 頁面中加入 try catch:
Test page in http://test.com - // app.js里面有一個foo方法,調用了不存在的bar方法
- // 運行輸出結果如下:
- => ReferenceError: bar is not defined
- at foo (http://another-domain.com/app.js:2:3)
- at http://test.com/:15:3
- => "Script error.", "", 0, 0, undefined
可見 try catch 中的 Console 語句輸出了完整的信息,但 window.onerror 中只能捕獲“Script error”。根據(jù)這個特點,可以在 catch 語句中手動上報捕獲的異常。
總結
上述的錯誤捕獲基本覆蓋了前端監(jiān)控所需的錯誤場景,但是第三部分指出的兩個其他問題,目前解決的方式都不太***。
對于有使用框架的項目:一是需要有額外的處理流程,比如示例中就需要單獨為vue項目進行初始化;二是對于其他框架,都需要單獨處理,例如react項目的話,則需要使用官方提供的componentDidCatch方法來做錯誤捕獲。
而對于跨域js捕獲的問題:我們并不能保證所有的跨域靜態(tài)資源都添加跨域 HTTP 響應頭;而通過第二種包裹try-catch的方式進行上報,則需要考慮的場景繁多并且無法保證沒有遺漏。
雖然存在這兩點不足,但前端錯誤捕獲這部分還是和項目的使用場景密切相關的。我們可以在了解這些方式以后,選擇最適合自己項目的方案,為自己的監(jiān)控工具服務。
新聞標題:一篇文章教你如何捕獲前端錯誤
本文來源:http://www.5511xx.com/article/ccegdhh.html


咨詢
建站咨詢
