優(yōu)雅處理前端異常的幾種方式推薦
一、為什么要處理異常?
1、未雨綢繆,盡早發(fā)現(xiàn)問題
2、讓異常變得可控,避免影響呈現(xiàn)結(jié)果
3、增強(qiáng)用戶體驗(yàn)
4、完善的前端方案
二、需要處理哪些異常?
1、JavaScript 語法錯(cuò)誤、代碼異常
2、異步請求異常
3、靜態(tài)資源加載異常
4、Promise 異常
5、跨域
6、崩潰與渲染異常
三、處理異常的方式有哪些?
1、try-catch
我們可以使用 try-catch 對同步代碼運(yùn)行異常進(jìn)行捕獲。
例如:
try { let name = 'leo'; console.log(age); } catch(e) { console.log('捕獲到異常:',e); } // 捕獲到異常: ReferenceError: age is not defined
try-catch 無法捕獲語法錯(cuò)誤和異步錯(cuò)誤。
例如:
try { let name = 'leo; // 缺少一個(gè)單引號,屬于語法錯(cuò)誤,在開發(fā)階段便提示出來 console.log(age); } catch(e) { console.log('捕獲到異常:',e); } // Uncaught SyntaxError: Invalid or unexpected token
try { setTimeout(() => { undefined.map(v => v*2); }, 1000) } catch(e) { console.log('捕獲到異常:',e); }
由于 setTimeout 屬于異步,try-catch 并沒有捕獲到,查看日志
// Uncaught TypeError: Cannot read property 'map' of undefined
2、window.onerror
我們可以使用 window.onerror 對 JavaScript 運(yùn)行錯(cuò)誤時(shí)進(jìn)行捕獲。
window.onerror = function(message, source, lineNo, colNo, error) { console.log('捕獲到異常:',{message, source, lineNo, colNo, error}); } /** * message 錯(cuò)誤信息 * source 出錯(cuò)文件 * lineNo 行號 * colNo 列號 * error Error對象(對象) */
同步運(yùn)行錯(cuò)誤
window.onerror = function(message, source, lineNo, colNo, error) { console.log('捕獲到異常:',{message, source, lineNo, colNo, error}); } leo;
捕獲到異常
語法錯(cuò)誤
window.onerror = function(message, source, lineNo, colNo, error) { console.log('捕獲到異常:',{message, source, lineNo, colNo, error}); } let name = 'leo
與 try-catch 一樣,無法捕獲語法錯(cuò)誤。
異步運(yùn)行錯(cuò)誤
window.onerror = function(message, source, lineNo, colNo, error) { console.log('捕獲到異常:',{message, source, lineNo, colNo, error}); } setTimeout(() => { leo; },1000)
捕獲到異常
window.onerror 在捕獲到錯(cuò)誤時(shí),會向上拋出,如上例,控制臺會出現(xiàn)
我們可以在函數(shù)里面使用 return true,使異常不向上拋出,此時(shí)控制臺不會顯示如上錯(cuò)誤信息
window.onerror = function(message, source, lineNo, colNo, error) { console.log('捕獲到異常:',{message, source, lineNo, colNo, error}); return true; // 異常不向上拋出 } setTimeout(() => { leo; },1000)
window.onerror 最好寫在所有 JavaScript 腳本前面,否則有可能捕獲不到異常;
window.onerror 無法捕獲語法異常、靜態(tài)資源異常、接口請求異常;
window.onerror 主要用來捕獲意料之外的異常,而 try-catch 則是用來捕獲可預(yù)見的異常。
3、window.addEventListener
我們可以使用 window.addEventListener 對靜態(tài)資源加載異常與接口請求異常進(jìn)行捕獲。
<scritp> window.addEventListener('error', (error) => { console.log('捕獲到異常:', error); }, true) </script> <img src="../../assets/test.png">
捕獲到異常
當(dāng)一項(xiàng)資源(如圖片或腳本)加載失敗,加載資源的元素會觸發(fā)一個(gè) Event 接口的 error 事件,并執(zhí)行該元素上的 onerror 處理函數(shù)。
由于網(wǎng)絡(luò)請求異常不會事件冒泡,因此必須在捕獲階段將其捕捉到才行,但是這種方式雖然可以捕捉到網(wǎng)絡(luò)請求的異常,但是無法判斷狀態(tài)碼是 404 還是其他比如 500 等等,所以還需要配合服務(wù)端日志才進(jìn)行排查分析才可以。
不同的瀏覽器返回的 error 對象可能不一樣,需要做兼容;
避免 addEventListener 重復(fù)監(jiān)聽。
4、Promise catch
我們可以使用 Promise 中的 catch 捕獲異步錯(cuò)誤。
new Promise((resolve,reject) => { reject("執(zhí)行失敗!") }).catch(error => { console.log("捕獲到異常:",error) })
捕獲到異常
有時(shí)候我們在寫 Promise 可能會漏掉 catch,所以建議在全局增加一個(gè)對 unhandledrejection 的監(jiān)聽,用來全局監(jiān)聽 Uncaught Promise Error。
window.addEventListener("unhandledrejection", function(e){ e.preventDefault() console.log('捕獲到異常:', e); }); new Promise((resolve,reject) => { reject("執(zhí)行失??!") })
捕獲到異常
添加 event.preventDefault(); 可以去掉控制臺的異常顯示信息。
5、vue errorHandler
我們可以使用 errorHandler 對 vue 組件中所拋錯(cuò)誤的捕捉與處理。
Vue.config.errorHandler = (err, vm, info) => { console.error(err); console.error(vm); console.error(info); } // 某個(gè)組件的 mounted const error = new Error('test error'); error.code = -1; throw error;
捕獲到異常
6、 react 異常捕獲
React 16 提供了一個(gè)內(nèi)置函數(shù) componentDidCatch
,使用它可以非常簡單的獲取到 react
下的錯(cuò)誤信息。
componentDidCatch(error, info) { console.log(error, info); }
除此之外,也可以使用錯(cuò)誤邊界 error boundary,此處不展開。
7、跨域
資源跨域可以為 script
標(biāo)簽添加 crossOrigin
屬性。
<script src="http://localhost:3000/main.js" crossorigin></script>
也可以動(dòng)態(tài)添加 JavaScript 腳本
const script = document.createElement('script'); script.crossOrigin = 'anonymous'; script.src = url; document.body.appendChild(script);
四、總結(jié)
處理異常方式 | 說明 |
---|---|
try-catch | 可預(yù)見、可疑區(qū)域 |
window.onerror | 全局捕獲 JavaScript 異常 |
window.addEventListener | 全局捕獲靜態(tài)資源異常 |
Promise catch | 捕獲 Promise 異常,也可使用 unhandledrejection 進(jìn)行全局捕獲 |
vue errorHandler | 捕獲 vue 異常 |
react 異常捕獲 | 捕獲 react 異常 |
crossOrigin | 解決 JavaScript 腳本跨域 |
到此這篇關(guān)于優(yōu)雅處理前端異常的幾種方式文章就介紹到這了,更多相關(guān)優(yōu)雅處理前端異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
前端如何利用CryptoJS實(shí)現(xiàn)數(shù)據(jù)信息的加密詳解
這篇文章主要給大家介紹了關(guān)于前端如何利用CryptoJS實(shí)現(xiàn)數(shù)據(jù)信息加密的相關(guān)資料,前端解密解密工具Cryptojs提供了前端加密解密的工作,包括常用的MD5、BASE64、SHA1、AES等加密解密方法,需要的朋友可以參考下2023-11-11javascript document.referrer 用法
document對象的referrer屬性,返回導(dǎo)航到當(dāng)前網(wǎng)頁的超鏈接所在網(wǎng)頁的URL。2009-04-04JSON序列化與解析原生JS方法且IE6和chrome測試通過
JSON序列化與解析本文通過原生JS方法實(shí)現(xiàn),IE6和chrome下均測試通過,喜歡的朋友可以嘗試操作下2013-09-09JavaScript自定義Promise實(shí)現(xiàn)流程
現(xiàn)在網(wǎng)上有非常多的Promise文章,但都是給你一堆代碼,或者某些核心代碼,讓你看完之后感覺,嗯,很厲害,但還是不知所云,不知其所以然。那么本文真正從一個(gè)小白開始帶你深入淺出,一步一步實(shí)現(xiàn)自己的?Promise,這種自己造輪子的過程一定是進(jìn)步最快的過程,快上車開始吧2022-10-10JavaScript接口的實(shí)現(xiàn)三種方式(推薦)
這篇文章主要介紹了JavaScript接口的實(shí)現(xiàn)三種方式,有注釋法,檢查屬性法和鴨式辨行法,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-06-06淺談javascript中的數(shù)據(jù)類型轉(zhuǎn)換
本文主要對javascript中的數(shù)據(jù)類型轉(zhuǎn)換進(jìn)行介紹,具有一定的參考價(jià)值,下面跟著小編一起來看下吧2016-12-12JavaScript高級程序設(shè)計(jì) 讀書筆記之八 Function類及閉包
Function類及閉包,學(xué)習(xí)js的朋友可以參考下2012-02-02