之前在公司時半抱,公司內(nèi)部有一個前端異常監(jiān)控系統(tǒng)脓恕,雖然會用,但是別人寫的窿侈,我一直不理解其中的實現(xiàn)原理炼幔,很慚愧用了那么久,竟然都沒有主動去了解了解其中的原理史简。昨天和一個同事聊天乃秀,他說這個監(jiān)控很簡單,就是用了window.onerror 監(jiān)聽錯誤然后AJAX發(fā)送給后臺圆兵。
跺讯??殉农?刀脏??超凳?愈污??轮傍?暂雹??创夜?杭跪??驰吓?揍魂??
原理這么簡單棚瘟?现斋??偎蘸?庄蹋?所以我決定徹底了解下異常監(jiān)控的一些知識
目前瞬内,實現(xiàn)前端異常監(jiān)控,除了用一些現(xiàn)成的框架限书,如果我們自己去實現(xiàn)虫蝶,可以怎么做?
(1) try-catch
這個方案不推薦倦西。
原因如下:
- 沒辦法捕捉到全局的錯誤事件能真,只有 try-catch 塊里面運行的錯誤才能被捕獲到。
- 太麻煩扰柠,不可能每一個地方都用 try-catch粉铐,而且,自己寫的代碼卤档,一般調(diào)試時候就會發(fā)現(xiàn)錯誤蝙泼,還用得著監(jiān)控?劝枣?汤踏?
(2) window.onerror
推薦做法,也是我們目前的做法
我們先來看看這個事件的用法:
/*
* @param msg{String}:錯誤消息
* @param url{String}:發(fā)生錯誤頁面的url
* @param line{Number}:發(fā)生錯誤的代碼行
*/
window.onerror = function(msg, url, line){
return true // 返回 true 則錯誤消息不顯示在控制臺舔腾,返回 false溪胶,則錯誤消息將會展示在控制臺
}
使用這個方法的前提是,必須把這塊代碼單獨分離出來稳诚,且在所有代碼執(zhí)行之前執(zhí)行哗脖,不然,自己的JS報錯采桃,監(jiān)控代碼還沒執(zhí)行懒熙,頁面就掛了,那還怎么監(jiān)控普办,哈哈哈哈工扎。
onerror 事件還有個好處,外部的加載的JS中出現(xiàn)了錯誤衔蹲,也可以監(jiān)聽得到肢娘,不過前提是這個外部JS文件不跨域
如果遇到外部跨域的JS文件,我們該怎么監(jiān)控呢舆驶?
如果你什么都不做橱健,那么如果跨域文件出現(xiàn)問題,只會返回一個錯誤提示:’Script error‘沙廉。這就蛋疼了拘荡,返回這個有什么用?撬陵?珊皿?
別急网缝,以下方法可以助你順利拿到詳細錯誤信息,來蟋定,跟著我往下看:
HTML5中粉臊,允許本地獲取到跨域腳本的錯誤信息,但有兩個條件:
- 跨域腳本的服務(wù)器必須通過 Access-Controll-Allow-Origin 頭信息允許當期域名可以獲取錯誤信息
- 當前域名的 script 標簽也必須指明src屬性指定的地址是支持跨域的地址驶兜,也就是 crossorigin 屬性
就像這樣:
<script src="..." crossorigin ></script>
通過這兩個設(shè)置扼仲,讓你的頁面盡情的去捕獲跨域錯誤吧!
可是抄淑,又有人要問了(這些人怎么問題這么多(∩_∩))
怎么用onerror去監(jiān)聽圖片的錯誤屠凶??
這個不難蝇狼,請聽我靜靜分(裝)析(逼):
一般的方案就是阅畴,因為onerror可以監(jiān)聽到圖片異常倡怎,比如圖片缺失迅耘,然后我們再手動為其指定一個默認圖片即可,不過监署,如果這個默認圖片也出錯颤专,那豈不是會造成錯誤一直循環(huán)提示?钠乏?栖秕?
怎么解決這個問題?晓避?
所以簇捍,請看以下代碼:
<img src="..." onerror="noFind();" />
function noFind(event){
var img = event.srcElement;
img.src = '...' // 默認圖片地址
img.onerror = null; // 控制不要循環(huán)展示錯誤
}
如果你使用了這段代碼,可以確保不會循環(huán)顯示錯誤