window.onerror()的用法與實(shí)例分析
onerror語(yǔ)法使用
onerror 默認(rèn)有三個(gè)入?yún)ⅲ?/p>
•msg: 錯(cuò)誤信息
•url:錯(cuò)誤所在文件
•line: 錯(cuò)誤所在代碼行,整型
window.onerror = function(msg, url, line){ // some code };
對(duì)于 <body onerror=”some code”>形式的,可以通過(guò)arguments[0]、arguments[1]、arguments[2]依次獲取參數(shù)。
js中我們最常用的就是js容錯(cuò)
window.onerror=function(){return true;}
基本特性
可以通過(guò)設(shè)置returnValue=true,或直接return true來(lái)阻止瀏覽器顯示錯(cuò)誤信息。但不會(huì)阻止script debuggers彈出的調(diào)試框。
只有運(yùn)行錯(cuò)誤才會(huì)觸發(fā)onerror,語(yǔ)法錯(cuò)誤不會(huì)觸發(fā)。
以下三種方式可以引發(fā)onerror:
•運(yùn)行時(shí)錯(cuò)誤,例如無(wú)效的對(duì)象引用或安全限制
•下載錯(cuò)誤,如圖片
•在IE9中,獲取多媒體數(shù)據(jù)失敗也會(huì)引發(fā)
<script> 標(biāo)簽不支持onerror。
定義在 <body> 標(biāo)簽上的onerror屬性相當(dāng)于window.onerror (經(jīng)測(cè)試,F(xiàn)irefox、Opera支持,IE9、chrome無(wú)反應(yīng))。
瀏覽器兼容性
QuirksMode列出的各瀏覽器對(duì)onError的支持情況
•Chrome 13+
•Firefox 6.1+
•Internet Explorer 5.5+
•Safari 5.1+
•Opera 11.61+ (QuirksMode 測(cè)試到11.51尚不支持,我手頭上的11.61已支持)
除window對(duì)象外,支持 onerror 的元素:
•<img> 全支持
•<script> IE9/IE10/safari 5.1+/chrome 13+ 支持
<css> 和 <iframe> 不支持onerror。
問(wèn)題與解決方案
對(duì)于引用外部js文件中的錯(cuò)誤,Webkit和Mozilla類(lèi)瀏覽器會(huì)篡改原始的錯(cuò)誤信息,導(dǎo)致最后onerror獲取到的三個(gè)入?yún)椋?/p>
“Script error.”,”", 0
例如http://a.com/index.html,引入了http://b.com/g.js,如果g.js出錯(cuò),最終傳遞到window.onerror的信息會(huì)被篡改。
瀏覽器之所以做這樣的處理,是考慮到兩個(gè)特性:
•<script> 能執(zhí)行非同源下的第三方j(luò)s文件。
•<script> 元素會(huì)忽略加載的文件的MIME類(lèi)型,而當(dāng)作腳本來(lái)執(zhí)行。
在攻擊場(chǎng)景中,惡意頁(yè)面引入了正常頁(yè)面的js文件,js文件會(huì)自動(dòng)執(zhí)行,若發(fā)生異常觸發(fā)的報(bào)錯(cuò)信息,可能會(huì)泄漏某些敏感數(shù)據(jù)。這些信息最終會(huì)被惡意頁(yè)面的window.onerror處理。
經(jīng)測(cè)試,存在此特性的瀏覽器(當(dāng)前最新版)有Firefox、Chrome、Safari、Opera。
Adam Barth(work on the security of the Chrome browser at Google)建議的解決方案是使用CORS (Cross-Origin Resource Sharing)。
簡(jiǎn)言之,當(dāng)在頁(yè)面中 <script> 引入外部js文件時(shí),增加一個(gè)屬性crossorigin(類(lèi)似于<img> 的CROS屬性)。服務(wù)器在接受到請(qǐng)求時(shí),在HTTP Header里增加一個(gè)授權(quán)字段(值可以是具體的某個(gè)域名):
Access-Control-Allow-Origin: *
瀏覽器檢測(cè)到此js已經(jīng)授權(quán)此頁(yè)面所在域名,則不用再篡改由此js傳遞到window.onerror的錯(cuò)誤信息了。
經(jīng)測(cè)試,此方案尚未被瀏覽器實(shí)現(xiàn)。
已經(jīng)在Chrome、Firefox的較新版本中支持。
其他參考資料
Internet Explorer http://msdn.microsoft.com/en-us/library/cc197053.aspx
Mozilla Firefox https://developer.mozilla.org/en/DOM/window.onerror
Opera http://dev.opera.com/articles/view/better-error-handling-with-window-onerror/
Wiki http://www.w3.org/wiki/DOM/window.onerror
syntax errors and runtime errors http://www.htmlgoodies.com/primers/jsp/article.php/3610081/Javascript-Basics-Part-11.htm
window.下面是一些實(shí)例大家可以參考下:
onerror = function(sMessage,sUrl,sLine){};
onerror函數(shù)的三個(gè)參數(shù)用于確定錯(cuò)誤確切的信息,代表的意思依次為:錯(cuò)誤信息;發(fā)生錯(cuò)誤的文件;發(fā)生錯(cuò)誤的行號(hào)。
示例:
<SCRIPT> window.onerror=fnErrorTrap; function fnErrorTrap(sMsg,sUrl,sLine){ oErrorLog.innerHTML="<b>An error was thrown and caught.</b><p>"; oErrorLog.innerHTML+="Error: " + sMsg + "<br>"; oErrorLog.innerHTML+="Line: " + sLine + "<br>"; oErrorLog.innerHTML+="URL: " + sUrl + "<br>"; return false; } function fnThrow(){ eval(oErrorCode.value); } </SCRIPT> <INPUT TYPE="text" ID=oErrorCode VALUE="someObject.someProperty=true;"> <INPUT TYPE="button" VALUE="Throw Error" onclick="fnThrow()"> <P> <DIV ID="oErrorLog"> </DIV>
上面示例的方法很值得借鑒。
在捕獲js錯(cuò)誤時(shí),我們通常使用try{}catch(e){}的方式,然后通過(guò)e.errorMessage等方式獲取錯(cuò)誤信息然后報(bào)告錯(cuò)誤。但對(duì)于onerror事件可能很少問(wèn)津,我們是否思考過(guò)如何報(bào)告錯(cuò)誤所在的行號(hào)?如果想過(guò)這個(gè)是否也被這個(gè)問(wèn)題所困擾過(guò),是否認(rèn)為在js里不可能捕獲錯(cuò)誤的行號(hào)呢?其實(shí)本人就遇到上述的幾個(gè)問(wèn)題,今日讀某人寫(xiě)的一段js代碼頓然發(fā)現(xiàn)了onerror事件,要說(shuō)onerror這個(gè)時(shí)間也是n久以前就知道了,但對(duì)于其所帶有的三個(gè)參數(shù)和其特殊性質(zhì)卻一直沒(méi)有去了解過(guò)。經(jīng)過(guò)自己的研究測(cè)試,對(duì)onerror事件有了一些新的認(rèn)識(shí)和了解。在頁(yè)面沒(méi)有錯(cuò)誤時(shí),window.onerror事件是不存在的,也就是null(廢話!沒(méi)出錯(cuò)如果onerror出現(xiàn)還正常嗎?)我們一般通過(guò)函數(shù)名傳遞的方式(引用的方式)將要執(zhí)行的操作函數(shù)傳遞給onerror事件,如window.onerror=reportError;window.onerror=function(){alert('error')},但我們可能不知道該事件觸發(fā)時(shí)還帶有三個(gè)默認(rèn)的參數(shù),他們分別是錯(cuò)誤信息,錯(cuò)誤頁(yè)面的url和錯(cuò)誤行號(hào)。要知道這個(gè)可是事件,就如onclick和onmouseover等事件一樣,但它是有參數(shù)。我們可以這樣測(cè)試。
<script type="text/javascript"> window.onerror=testError; function testError(){ arglen=arguments.length; var errorMsg="參數(shù)個(gè)數(shù):"+arglen+"個(gè)"; for(var i=0;i<arglen;i++){ errorMsg+="/n參數(shù)"+(i+1)+":"+arguments[i]; } alert(errorMsg); window.onerror=null; return true; } function test(){ error } test() </script>
首先將testError方法綁定給onerror事件,然后在test方法里觸發(fā)一個(gè)錯(cuò)誤,在IE中執(zhí)行時(shí)我們發(fā)現(xiàn)如下提示:
--------------------------- Microsoft Internet Explorer ---------------------------
參數(shù)個(gè)數(shù):3個(gè)
參數(shù)1:'error' 未定義
參數(shù)2:file://E:/yanwei/test/testError.html
參數(shù)3:14
--------------------------- 確定 ---------------------------
可以發(fā)現(xiàn),當(dāng)出錯(cuò)時(shí)函數(shù)testError捕獲到了三個(gè)參數(shù)。通過(guò)將函數(shù)綁定到onerror事件就可以在頁(yè)面出錯(cuò)時(shí)捕獲以上三個(gè)參數(shù)。
在測(cè)試中還發(fā)現(xiàn)以下一些問(wèn)題:
1、通過(guò)在函數(shù)末尾加上return true,可以在函數(shù)出錯(cuò)時(shí)不會(huì)彈出系統(tǒng)的錯(cuò)誤信息(IE)。
2、如果頁(yè)面出現(xiàn)多次錯(cuò)誤,只捕獲第一次錯(cuò)誤并進(jìn)行處理然后終止后面程序的執(zhí)行。
3、onerror事件并不能捕獲所有的錯(cuò)誤,只能捕獲函數(shù)外或函數(shù)內(nèi)錯(cuò)誤(??這個(gè)是什么意思,可不是開(kāi)玩笑呢),如 adasdf; function test(){ aaaa; } 可以捕獲到adasdf未定義的錯(cuò)誤 function test(){ aaaa; } 可以捕獲到aaaa未定義的錯(cuò)誤,而對(duì)于functiona test(){}或function test()dd{} 的錯(cuò)誤卻不能捕獲而會(huì)直接彈出系統(tǒng)錯(cuò)誤信息。
4、onerror在IE和FF等瀏覽器執(zhí)行方式是一樣的,而且都包含這三個(gè)參數(shù)。
相關(guān)文章
javascript實(shí)現(xiàn)的HashMap類(lèi)代碼
這篇文章主要介紹了javascript實(shí)現(xiàn)的HashMap類(lèi)代碼,實(shí)現(xiàn)了添加、獲取、刪除、查詢key和value功能,需要的朋友可以參考下2014-06-06詳解javascript實(shí)現(xiàn)瀑布流列式布局
這篇文章主要介紹了javascript實(shí)現(xiàn)瀑布流的兩種布局方式,一是絕對(duì)式布局、二是列式布局,詳細(xì)介紹了這兩種布局方式的原理,本文重點(diǎn)介紹列式布局,感興趣的小伙伴們可以參考一下2016-01-01短視頻(douyin)去水印工具的實(shí)現(xiàn)代碼
這篇文章主要介紹了市面上短視頻(douyin)"去水印"的工具原來(lái)是這樣實(shí)現(xiàn)的,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03uniapp基礎(chǔ)知識(shí)點(diǎn)掌握以及面試題整理
uni-app是一個(gè)使用vue.js開(kāi)發(fā)所有前端應(yīng)用的框架,開(kāi)發(fā)者編寫(xiě)一套代碼,下面這篇文章主要給大家介紹了關(guān)于uniapp基礎(chǔ)知識(shí)點(diǎn)掌握以及面試題整理的相關(guān)資料,需要的朋友可以參考下2023-02-02淺析JavaScript 函數(shù)防抖和節(jié)流
這篇文章主要介紹了JavaScript 函數(shù)防抖和節(jié)流的相關(guān)資料,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07js父頁(yè)面與子頁(yè)面不同時(shí)顯示的方法
這篇文章主要介紹了js父頁(yè)面與子頁(yè)面不同時(shí)顯示的方法,打開(kāi)一個(gè)頁(yè)面后,父頁(yè)面DISABLE,在子頁(yè)面關(guān)閉后,父頁(yè)面ENABLE,是比較實(shí)用的技巧,需要的朋友可以參考下2014-10-10JavaScript實(shí)現(xiàn)像素鳥(niǎo)小游戲的詳細(xì)流程
最近通過(guò)javascript這門(mén)語(yǔ)言,然后結(jié)合html的來(lái)寫(xiě)一個(gè)簡(jiǎn)單的小游戲 ,這篇文章主要給大家介紹了關(guān)于JavaScript實(shí)現(xiàn)像素鳥(niǎo)小游戲的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07webpack3里使用uglifyjs壓縮js時(shí)打包報(bào)錯(cuò)的解決
這篇文章主要介紹了webpack3里使用uglifyjs壓縮js時(shí)打包報(bào)錯(cuò)的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12