前端監(jiān)控頁面異常的常用方法
前端開發(fā)常見問題之一: 資源異常、js異常;
頁面出了問題常見的想法是:如何看到錯誤信息,資源腳本是否正常;
像js、css、圖片這些資源文件經(jīng)常受網(wǎng)絡(luò)等原因,導(dǎo)致資源加載異常,這些會直接影響我們的頁面; 所以我們也需要有對資源加載是否正常有監(jiān)控;
1.資源加載錯誤監(jiān)控
這塊主要是對資源加載錯誤,找不到文件或者網(wǎng)絡(luò)原因?qū)е沦Y源加載超時導(dǎo)致的失??;
常用方法:
- 添加一個error監(jiān)聽函數(shù)捕獲方法:
該方法是相對比較推薦,因為頁面error監(jiān)聽函數(shù)可以捕獲到頁面所有移除信息,只需要自行獲取異常信息即可;
參考一個例子
/** * 監(jiān)控頁面靜態(tài)資源加載報錯 */ function loadResourceError() { window.addEventListener('error', function(e) { console.log(e, '錯誤捕獲==='); if(e){ let target = e.target || e.srcElement; let isElementTarget = target instanceof HTMLElement; if (!isElementTarget) { // js錯誤 console.log('js錯誤==='); // js error處理 let { filename, message, lineno, colno, error} = e; let { message: ErrorMsg, stack } = error; }else{ // 頁面靜態(tài)資源加載錯誤處理 console.log('資源加載錯誤==='); let { type, timeStamp, target } = e; let { localName, outerHTML, tagName, src } = target; let typeName = target.localName; let sourceUrl = ""; if (typeName === "link") { sourceUrl = target.href; } else if (typeName === "script") { sourceUrl = target.src; } alert('資源加載失敗,請刷新頁面或切換網(wǎng)絡(luò)重試。('+sourceUrl+')') } } // 注意:由于網(wǎng)絡(luò)請求異常不會事件冒泡,因此必須在捕獲階段才能捕獲到異常; // 設(shè)為true表示捕獲階段調(diào)用,會在元素的onerror前調(diào)用,在window.addEventListener('error')后調(diào)用 },true); } // 我們根據(jù)e.target的屬性來判斷它是link標(biāo)簽,還是script標(biāo)簽。目前只關(guān)注只監(jiān)控了css,js文件加載錯誤的情況。
運行結(jié)果
補充一個知識點:
window.addEventListener('error') 與 window.onerror 有什么區(qū)別?
window.addEventListener('error') 和 window.onerror 都是用來捕獲全局錯誤的方法,但它們在使用方式、功能特性以及適用場景上有所不同。
定義:
window.onerror 是一個全局事件處理函數(shù),當(dāng)有JavaScript運行時錯誤發(fā)生時,會自動調(diào)用該函數(shù)。它接受五個參數(shù):錯誤信息(message)、發(fā)生錯誤的腳本URL(source)、行號(lineno)、列號(colno)和錯誤對象(error)。如果該函數(shù)返回true,則阻止默認(rèn)的事件處理函數(shù)執(zhí)行;如果返回false或不返回,錯誤信息會在控制臺中打印
window.addEventListener('error') 通過事件監(jiān)聽的方式來捕獲錯誤。它可以綁定多個回調(diào)函數(shù),并且會按照順序執(zhí)行這些回調(diào)函數(shù)。與window.onerror不同,addEventListener的回調(diào)函數(shù)不會自動執(zhí)行,需要顯式添加。它也可以在捕獲階段捕獲錯誤,適用于需要精確控制錯誤處理流程的場景
功能:
捕獲錯誤的范圍:window.addEventListener('error') 可以在捕獲階段捕獲錯誤,比 window.onerror 更早觸發(fā)。它不僅可以捕獲js運行時錯誤,還可以捕獲網(wǎng)絡(luò)請求錯誤(如果設(shè)置為在捕獲階段執(zhí)行),但無法捕獲Promise相關(guān)的錯誤和資源加載異常
錯誤處理:window.onerror 可以接受多個參數(shù),提供更詳細的錯誤信息。它可以在錯誤發(fā)生時立即處理,但無法捕獲Promise錯誤和資源加載異常。而 window.addEventListener('error') 可以綁定多個回調(diào)函數(shù),提供更靈活的錯誤處理機制
使用:
window.onerror 適用于需要立即處理全局JavaScript錯誤的場景,尤其是在無法使用try-catch的情況下。它適合簡單的錯誤捕獲和處理,但由于其限制,不適合復(fù)雜的錯誤管理和異步錯誤處理
window.addEventListener('error') 適用于需要更靈活和精確控制錯誤處理的場景。它適合復(fù)雜的Web應(yīng)用,特別是那些需要捕獲和處理多種類型錯誤的場景。通過在捕獲階段使用,它還可以捕獲網(wǎng)絡(luò)請求錯誤,但需要注意同源策略的限制
performance.getEntries()方法:
可以獲取到當(dāng)前所有加載成功的資源列表。 然后在onload事件中遍歷出所有資源集合。 再從所有列表中過濾出成功的資源列表,剩下的就是加載失敗的資源;
雖然能排查出一些加載失敗的靜態(tài)資源,但受到檢查時機的影響,還有遇到遇到異步加載的js也沒有辦法處理;
看個例子
// 瀏覽器獲取網(wǎng)頁時會對網(wǎng)頁中每一個對象(腳本文件、樣式表、圖片文件等等)發(fā)出一個HTTP請求。而通過window.performance.getEntries方法,則可以以數(shù)組形式,返回這些請求的時間統(tǒng)計信息,每個數(shù)組成員均是一個PerformanceResourceTiming對象! //原理是通過捕獲瀏覽器發(fā)出的http請求信息 function performanceGetEntries(){ // 判斷瀏覽器是否支持 if (!window.performance && !window.performance.getEntries) { return false; } var result = []; // 獲取當(dāng)前頁面所有請求對應(yīng)的PerformanceResourceTiming對象進行分析 window.performance.getEntries().forEach((item) => { result.push({ 'url': item.name, 'entryType': item.entryType, 'type': item.initiatorType, 'duration(ms)': item.duration }); }); // 控制臺輸出統(tǒng)計結(jié)果 console.table(result); // 表示已經(jīng)加載的資源 -這是加載成功的列表 //一個最簡單的方法是數(shù)量相差得出失敗的數(shù)量 // 然后把整個資源的數(shù)量減去已經(jīng)加載好的資源,剩下的就是沒有加載出來的資源的數(shù)量。 }
運行效果
- onerror 方法:
指定具體的靜態(tài)資源,如某個圖片元素
圖片: let image = document.getElementByid('#img') image.onerror = (e)=>{ //錯誤信息 console.log(e) } js腳本 let script = document.createElement('script'); script.onload = function() { console.log('腳本加載成功'); // 腳本加載成功后的操作 }; script.onerror = function() { console.error('腳本加載失敗'); // 腳本加載失敗后的操作 };
2. js邏輯異常
- 代碼邏輯中
直接用try catch獲取js錯誤信息和上報
在可能拋出異常的代碼塊使用try……catch結(jié)構(gòu),可以捕獲并處理這些錯誤;
try { // 嘗試執(zhí)行的代碼 someFunctionThatMightThrow(); } catch (error) { // 錯誤處理 console.error('捕獲到錯誤:', error); reportError(error); // 自定義的錯誤上報函數(shù) }
- 全局錯誤監(jiān)聽
為整個JavaScript環(huán)境添加全局錯誤監(jiān)聽器,可以捕獲未被捕獲的異常。即 window.onerror方法, 由于上面已經(jīng)介紹過,這里就重復(fù)介紹;
window.onerror = function(message, source, lineno, colno, error) { console.error('全局錯誤捕獲:', message, '在', source, '行', lineno); reportError(message, source, lineno); // 自定義的錯誤上報函數(shù) return false; // 返回false阻止默認(rèn)的錯誤頁面顯示 };
- 添加error監(jiān)方法
使用window.addEventListener監(jiān)聽捕獲異常,上面已經(jīng)介紹過,這里就不重復(fù)介紹;
window.addEventListener('error', function(event) { var message = event.message; var filename = event.filename || event.filename; var lineno = event.lineno; var colno = event.colno; var error = event.error; // Error object if available console.error('未捕獲的異常:', message, '在', filename, '行', lineno); reportError(message, filename, lineno); // 自定義的錯誤上報函數(shù) }, true); // 使用capture參數(shù)為true來捕獲事件冒泡階段的事件
- 使用第三方sdk
總結(jié)
前端監(jiān)控頁面異常設(shè)計的時候,可以考慮:1.window.addEventListener ;2.window.onerror;
都可以覆蓋資源加載異常和業(yè)務(wù)邏輯異常
到此這篇關(guān)于前端監(jiān)控頁面異常的常用方法的文章就介紹到這了,更多相關(guān)前端監(jiān)控頁面異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript基于DOM實現(xiàn)省市級聯(lián)下拉框的方法
這篇文章主要介紹了javascript基于DOM實現(xiàn)省市級聯(lián)下拉框的方法,可實現(xiàn)選擇省份后出現(xiàn)對應(yīng)城市下拉框選項的功能,非常具有實用價值,需要的朋友可以參考下2015-05-05Bootstrap模態(tài)對話框中顯示動態(tài)內(nèi)容的方法
今天小編就為大家分享一篇Bootstrap模態(tài)對話框中顯示動態(tài)內(nèi)容的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08