window.onerror()的用法与实例分析
onerror语法使用
onerror默认有三个入参:
•msg:错误信息
•url:错误所在文件
•line:错误所在代码行,整型
window.onerror=function(msg,url,line){//somecode};
对于<bodyonerror=”somecode”>形式的,可以通过arguments[0]、arguments[1]、arguments[2]依次获取参数。
js中我们最常用的就是js容错
window.onerror=function(){returntrue;}
基本特性
可以通过设置returnValue=true,或直接returntrue来阻止浏览器显示错误信息。但不会阻止scriptdebuggers弹出的调试框。
只有运行错误才会触发onerror,语法错误不会触发。
以下三种方式可以引发onerror:
•运行时错误,例如无效的对象引用或安全限制
•下载错误,如图片
•在IE9中,获取多媒体数据失败也会引发
<script>标签不支持onerror。
定义在<body>标签上的onerror属性相当于window.onerror(经测试,Firefox、Opera支持,IE9、chrome无反应)。
浏览器兼容性
QuirksMode列出的各浏览器对onError的支持情况
•Chrome13+
•Firefox6.1+
•InternetExplorer5.5+
•Safari5.1+
•Opera11.61+(QuirksMode测试到11.51尚不支持,我手头上的11.61已支持)
除window对象外,支持onerror的元素:
•<img>全支持
•<script>IE9/IE10/safari5.1+/chrome13+支持
<css>和<iframe>不支持onerror。
问题与解决方案
对于引用外部js文件中的错误,Webkit和Mozilla类浏览器会篡改原始的错误信息,导致最后onerror获取到的三个入参为:
“Scripterror.”,”",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。
AdamBarth(workonthesecurityoftheChromebrowseratGoogle)建议的解决方案是使用CORS(Cross-OriginResourceSharing)。
简言之,当在页面中<script>引入外部js文件时,增加一个属性crossorigin(类似于<img>的CROS属性)。服务器在接受到请求时,在HTTPHeader里增加一个授权字段(值可以是具体的某个域名):
Access-Control-Allow-Origin:*
浏览器检测到此js已经授权此页面所在域名,则不用再篡改由此js传递到window.onerror的错误信息了。
经测试,此方案尚未被浏览器实现。
已经在Chrome、Firefox的较新版本中支持。
其他参考资料
InternetExplorerhttp://msdn.microsoft.com/en-us/library/cc197053.aspx
MozillaFirefoxhttps://developer.mozilla.org/en/DOM/window.onerror
Operahttp://dev.opera.com/articles/view/better-error-handling-with-window-onerror/
Wikihttp://www.w3.org/wiki/DOM/window.onerror
syntaxerrorsandruntimeerrorshttp://www.htmlgoodies.com/primers/jsp/article.php/3610081/Javascript-Basics-Part-11.htm
window.下面是一些实例大家可以参考下:
onerror=function(sMessage,sUrl,sLine){};
onerror函数的三个参数用于确定错误确切的信息,代表的意思依次为:错误信息;发生错误的文件;发生错误的行号。
示例:
<SCRIPT> window.onerror=fnErrorTrap; functionfnErrorTrap(sMsg,sUrl,sLine){ oErrorLog.innerHTML="<b>Anerrorwasthrownandcaught.</b><p>"; oErrorLog.innerHTML+="Error:"+sMsg+"<br>"; oErrorLog.innerHTML+="Line:"+sLine+"<br>"; oErrorLog.innerHTML+="URL:"+sUrl+"<br>"; returnfalse; } functionfnThrow(){ eval(oErrorCode.value); } </SCRIPT> <INPUTTYPE="text"ID=oErrorCodeVALUE="someObject.someProperty=true;"> <INPUTTYPE="button"VALUE="ThrowError"onclick="fnThrow()"> <P> <DIVID="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等事件一样,但它是有参数。我们可以这样测试。
<scripttype="text/javascript"> window.onerror=testError; functiontestError(){ arglen=arguments.length; varerrorMsg="参数个数:"+arglen+"个"; for(vari=0;i<arglen;i++){ errorMsg+="/n参数"+(i+1)+":"+arguments[i]; } alert(errorMsg); window.onerror=null; returntrue; } functiontest(){ error } test() </script>
首先将testError方法绑定给onerror事件,然后在test方法里触发一个错误,在IE中执行时我们发现如下提示:
---------------------------MicrosoftInternetExplorer---------------------------
参数个数:3个
参数1:'error'未定义
参数2:file://E:/yanwei/test/testError.html
参数3:14
---------------------------确定---------------------------
可以发现,当出错时函数testError捕获到了三个参数。通过将函数绑定到onerror事件就可以在页面出错时捕获以上三个参数。
在测试中还发现以下一些问题:
1、通过在函数末尾加上returntrue,可以在函数出错时不会弹出系统的错误信息(IE)。
2、如果页面出现多次错误,只捕获第一次错误并进行处理然后终止后面程序的执行。
3、onerror事件并不能捕获所有的错误,只能捕获函数外或函数内错误(??这个是什么意思,可不是开玩笑呢),如adasdf;functiontest(){aaaa;}可以捕获到adasdf未定义的错误functiontest(){aaaa;}可以捕获到aaaa未定义的错误,而对于functionatest(){}或functiontest()dd{}的错误却不能捕获而会直接弹出系统错误信息。
4、onerror在IE和FF等浏览器执行方式是一样的,而且都包含这三个参数。