用window.onerror捕獲并上報(bào)Js錯(cuò)誤的方法
前兩天有個(gè)2048游戲的用戶反饋說,打開游戲后不能玩兒,只有一個(gè)游戲面板,數(shù)字無法初始化,更無法移動(dòng),設(shè)備為iPhone 4S、iOS 5.1。嘗試從微信調(diào)起Safari打開,依然不好使。由于游戲中運(yùn)用了比較多的HTML5特性,所以粗略估計(jì)是有JS報(bào)錯(cuò)導(dǎo)致。不過這樣的信息該如何捕獲到呢?當(dāng)然是傳說中的window.onerror。
從W3C找到關(guān)于window.onerror的方法體介紹:

這個(gè)意思,基本可以就是說,window.onerror方法,我們可以寫成:
/**
* @param {String} errorMessage 錯(cuò)誤信息
* @param {String} scriptURI 出錯(cuò)的文件
* @param {Long} lineNumber 出錯(cuò)代碼的行號(hào)
* @param {Long} columnNumber 出錯(cuò)代碼的列號(hào)
* @param {Object} errorObj 錯(cuò)誤的詳細(xì)信息,Anything
*/
window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) {
// TODO
}
不過使用過程中還得注意兼容性問題,不是所有瀏覽器都有參數(shù)列表中的所有參數(shù),chrome之類的,都是瀏覽器標(biāo)準(zhǔn)草案的領(lǐng)跑者,這些個(gè)參數(shù)用就是了!
于是,可以寫一個(gè)小Demo來嘗試一下:
<!DOCTYPE html>
<html>
<head>
<title>Js錯(cuò)誤捕獲</title>
<script type="text/javascript">
/**
* @param {String} errorMessage 錯(cuò)誤信息
* @param {String} scriptURI 出錯(cuò)的文件
* @param {Long} lineNumber 出錯(cuò)代碼的行號(hào)
* @param {Long} columnNumber 出錯(cuò)代碼的列號(hào)
* @param {Object} errorObj 錯(cuò)誤的詳細(xì)信息,Anything
*/
window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) {
console.log("錯(cuò)誤信息:" , errorMessage);
console.log("出錯(cuò)文件:" , scriptURI);
console.log("出錯(cuò)行號(hào):" , lineNumber);
console.log("出錯(cuò)列號(hào):" , columnNumber);
console.log("錯(cuò)誤詳情:" , errorObj);
}
</script>
</head>
<body>
<script type="text/javascript" src="error.js"></script>
</body>
</html>
其中error.js文件中的內(nèi)容,簡(jiǎn)單的這樣寫一句:
throw new Error("出錯(cuò)了!");
用瀏覽器跑起來以后,打開console,基本就是這樣的了:

所以,這些數(shù)據(jù)都是可以做上報(bào)的了。
當(dāng)然了,上面的error.js是和html頁(yè)面同域名下,如果error.js不在同域下,會(huì)是怎樣的?我們把error.js的引用改一下:
<script type="text/javascript" src="http://doitbegin.duapp.com/error.js"></script>
再來打開console,我們看到的是這樣的:

相當(dāng)于window.onerror方法只捕獲到了一個(gè)errorMessage,而且是固定字符串,毫無參考價(jià)值。查了點(diǎn)資料(Webkit源碼),發(fā)現(xiàn)在瀏覽器實(shí)現(xiàn)script資源加載的地方,是進(jìn)行了同源策略判斷的,如果是非同源資源,errorMessage就被寫死為“Script error”了:

好在script標(biāo)簽有一個(gè)crossorigin屬性,設(shè)置它可以顯示比較詳細(xì)的錯(cuò)誤信息,我們?cè)囍鴮cript標(biāo)簽改一下:
<script type="text/javascript" src="http://doitbegin.duapp.com/error.js" crossorigin></script>
刷新頁(yè)面,這個(gè)時(shí)候看到console中的輸出是這樣的:

出現(xiàn)這個(gè)error也不意外,既然設(shè)置了error.js為crossorigin,那error.js的HTTP Response Header也必須設(shè)置非同源可訪問。為了方便設(shè)置Header,把error.js做一個(gè)小改動(dòng),更名為:error-js.php。
<?php
header('Access-Control-Allow-Origin:*');
header('Content-type:text/javascript');
?>
throw new Error('出錯(cuò)了');
此時(shí)刷新頁(yè)面,看到console中的輸出就已經(jīng)正常了,所有信息都能正常捕獲:

OK,技術(shù)細(xì)節(jié)分析結(jié)束!我2048游戲靜態(tài)資源是放到靜態(tài)域(非同源)下的,所以要想通過window.onerror捕獲錯(cuò)誤信息,就得按照上面的最后一種情況來操作了:
1、添加script的crossorigin屬性
2、配置一下服務(wù)器,設(shè)置靜態(tài)資源Javascript的Response為Access-Control-Allow-Origin
相關(guān)文章
ko knockoutjs動(dòng)態(tài)屬性綁定技巧應(yīng)用
ko的動(dòng)態(tài)屬性是指,ViewModel不確定的屬性,而后期卻需要的屬性,本文將詳細(xì)介紹,需要的朋友參考下2012-11-11
使用layui實(shí)現(xiàn)的左側(cè)菜單欄以及動(dòng)態(tài)操作tab項(xiàng)方法
今天小編就為大家分享一篇使用layui實(shí)現(xiàn)的左側(cè)菜單欄以及動(dòng)態(tài)操作tab項(xiàng)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09
javascript自定義右鍵彈出菜單實(shí)現(xiàn)方法
這篇文章主要介紹了javascript自定義右鍵彈出菜單實(shí)現(xiàn)方法,涉及javascript操作鼠標(biāo)事件及頁(yè)面元素的相關(guān)技巧,需要的朋友可以參考下2015-05-05
JS動(dòng)態(tài)增加刪除UL節(jié)點(diǎn)LI及相關(guān)內(nèi)容示例
這篇文章主要介紹了JS如何動(dòng)態(tài)增加刪除UL節(jié)點(diǎn)LI及相關(guān)內(nèi)容,需要的朋友可以參考下2014-05-05
JS控制一個(gè)DIV層在指定時(shí)間內(nèi)消失的方法
這篇文章主要介紹了JS控制一個(gè)DIV層在指定時(shí)間內(nèi)消失的方法,需要的朋友可以參考下2014-02-02
原生JavaScript實(shí)現(xiàn)異步多文件上傳
這篇文章主要介紹了原生JavaScript實(shí)現(xiàn)異步多文件上傳,感興趣的小伙伴們可以參考一下2015-12-12
Three.js實(shí)現(xiàn)瀏覽器變動(dòng)時(shí)進(jìn)行自適應(yīng)的方法
這篇文章主要給大家介紹了關(guān)于Three.js實(shí)現(xiàn)瀏覽器變動(dòng)時(shí)進(jìn)行自適應(yīng)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09

