onerror語法使用
onerror 默認有三個入參:
•msg: 錯誤信息
•url:錯誤所在文件
•line: 錯誤所在代碼行,整型
window.onerror = function(msg, url, line){ // some code };
對於 <body onerror=”some code”>形式的,可以通過arguments[0]、arguments[1]、arguments[2]依次獲取參數。
js中我們最常用的就是js容錯
window.onerror=function(){return true;}
基本特性
可以通過設置returnValue=true,或直接return true來阻止浏覽器顯示錯誤信息。但不會阻止script debuggers彈出的調試框。
只有運行錯誤才會觸發onerror,語法錯誤不會觸發。
以下三種方式可以引發onerror:
•運行時錯誤,例如無效的對象引用或安全限制
•下載錯誤,如圖片
•在IE9中,獲取多媒體數據失敗也會引發
<script> 標簽不支持onerror。
定義在 <body> 標簽上的onerror屬性相當於window.onerror (經測試,Firefox、Opera支持,IE9、chrome無反應)。
浏覽器兼容性
QuirksMode列出的各浏覽器對onError的支持情況
•Chrome 13+
•Firefox 6.1+
•Internet Explorer 5.5+
•Safari 5.1+
•Opera 11.61+ (QuirksMode 測試到11.51尚不支持,我手頭上的11.61已支持)
除window對象外,支持 onerror 的元素:
•<img> 全支持
•<script> IE9/IE10/safari 5.1+/chrome 13+ 支持
<css> 和 <iframe> 不支持onerror。
問題與解決方案
對於引用外部js文件中的錯誤,Webkit和Mozilla類浏覽器會篡改原始的錯誤信息,導致最後onerror獲取到的三個入參為:
復制代碼 代碼如下:
“Script error.”,”", 0
例如http://a.com/index.html,引入了http://b.com/g.js,如果g.js出錯,最終傳遞到window.onerror的信息會被篡改。
浏覽器之所以做這樣的處理,是考慮到兩個特性:
•<script> 能執行非同源下的第三方js文件。
•<script> 元素會忽略加載的文件的MIME類型,而當作腳本來執行。
在攻擊場景中,惡意頁面引入了正常頁面的js文件,js文件會自動執行,若發生異常觸發的報錯信息,可能會洩漏某些敏感數據。這些信息最終會被惡意頁面的window.onerror處理。
經測試,存在此特性的浏覽器(當前最新版)有Firefox、Chrome、Safari、Opera。
Adam Barth(work on the security of the Chrome browser at Google)建議的解決方案是使用CORS (Cross-Origin Resource Sharing)。
簡言之,當在頁面中 <script> 引入外部js文件時,增加一個屬性crossorigin(類似於<img> 的CROS屬性)。服務器在接受到請求時,在HTTP Header裡增加一個授權字段(值可以是具體的某個域名):
Access-Control-Allow-Origin: *
浏覽器檢測到此js已經授權此頁面所在域名,則不用再篡改由此js傳遞到window.onerror的錯誤信息了。
經測試,此方案尚未被浏覽器實現。
已經在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.下面是一些實例大家可以參考下:
onerror = function(sMessage,sUrl,sLine){};
onerror函數的三個參數用於確定錯誤確切的信息,代表的意思依次為:錯誤信息;發生錯誤的文件;發生錯誤的行號。
示例:
<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錯誤時,我們通常使用try{}catch(e){}的方式,然後通過e.errorMessage等方式獲取錯誤信息然後報告錯誤。但對於onerror事件可能很少問津,我們是否思考過如何報告錯誤所在的行號?如果想過這個是否也被這個問題所困擾過,是否認為在js裡不可能捕獲錯誤的行號呢?其實本人就遇到上述的幾個問題,今日讀某人寫的一段js代碼頓然發現了onerror事件,要說onerror這個時間也是n久以前就知道了,但對於其所帶有的三個參數和其特殊性質卻一直沒有去了解過。經過自己的研究測試,對onerror事件有了一些新的認識和了解。在頁面沒有錯誤時,window.onerror事件是不存在的,也就是null(廢話!沒出錯如果onerror出現還正常嗎?)我們一般通過函數名傳遞的方式(引用的方式)將要執行的操作函數傳遞給onerror事件,如window.onerror=reportError;window.onerror=function(){alert('error')},但我們可能不知道該事件觸發時還帶有三個默認的參數,他們分別是錯誤信息,錯誤頁面的url和錯誤行號。要知道這個可是事件,就如onclick和onmouseover等事件一樣,但它是有參數。我們可以這樣測試。
<script type="text/javascript"> window.onerror=testError; function testError(){ arglen=arguments.length; var errorMsg="參數個數:"+arglen+"個"; for(var i=0;i<arglen;i++){ errorMsg+="/n參數"+(i+1)+":"+arguments[i]; } alert(errorMsg); window.onerror=null; return true; } function test(){ error } test() </script>
首先將testError方法綁定給onerror事件,然後在test方法裡觸發一個錯誤,在IE中執行時我們發現如下提示:
--------------------------- Microsoft Internet Explorer ---------------------------
參數個數:3個
參數1:'error' 未定義
參數2:file://E:/yanwei/test/testError.html
參數3:14
--------------------------- 確定 ---------------------------
可以發現,當出錯時函數testError捕獲到了三個參數。通過將函數綁定到onerror事件就可以在頁面出錯時捕獲以上三個參數。
在測試中還發現以下一些問題:
1、通過在函數末尾加上return true,可以在函數出錯時不會彈出系統的錯誤信息(IE)。
2、如果頁面出現多次錯誤,只捕獲第一次錯誤並進行處理然後終止後面程序的執行。
3、onerror事件並不能捕獲所有的錯誤,只能捕獲函數外或函數內錯誤(??這個是什麼意思,可不是開玩笑呢),如 adasdf; function test(){ aaaa; } 可以捕獲到adasdf未定義的錯誤 function test(){ aaaa; } 可以捕獲到aaaa未定義的錯誤,而對於functiona test(){}或function test()dd{} 的錯誤卻不能捕獲而會直接彈出系統錯誤信息。
4、onerror在IE和FF等浏覽器執行方式是一樣的,而且都包含這三個參數。