window.onerror()的用法与实例分析


Posted in Javascript onJanuary 27, 2016

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等浏览器执行方式是一样的,而且都包含这三个参数。

Javascript 相关文章推荐
Jquery Ajax.ashx 高效分页实现代码
Oct 20 Javascript
jQuery实现的类flash菜单效果代码
May 17 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
Jul 29 Javascript
jQuery实现简单滚动动画效果
Apr 07 Javascript
详解使用grunt完成requirejs的合并压缩和js文件的版本控制
Mar 02 Javascript
AngularJS学习笔记之表单验证功能实例详解
Jul 06 Javascript
基于JavaScript实现弹幕特效
Aug 27 Javascript
vue.js 实现输入框动态添加功能
Jun 25 Javascript
解决angularjs service中依赖注入$scope报错的问题
Oct 02 Javascript
移动端自适应flexible.js的使用方法(不用三大框架,仅写一个单html页面使用)推荐
Apr 02 Javascript
五分钟搞懂Vuex实用知识(小结)
Aug 12 Javascript
js实现简单的轮播图效果
Dec 13 Javascript
用window.onerror捕获并上报Js错误的方法
Jan 27 #Javascript
jquery实现可旋转可拖拽的文字效果代码
Jan 27 #Javascript
jquery+css3实现会动的小圆圈效果
Jan 27 #Javascript
再谈JavaScript异步编程
Jan 27 #Javascript
简单介绍jsonp 使用小结
Jan 27 #Javascript
理解javascript异步编程
Jan 27 #Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
Jan 27 #Javascript
You might like
解析PHP中VC6 X86和VC9 X86的区别及 Non Thread Safe的意思
2013/06/28 PHP
table标签的结构与合并单元格的实现方法
2013/07/24 PHP
smarty模板局部缓存方法使用示例
2014/06/17 PHP
PHP图像处理类库及演示分享
2015/05/17 PHP
PHPStorm+XDebug进行调试图文教程
2016/06/13 PHP
JS动画效果代码3
2008/04/03 Javascript
基于jquery的关于动态创建DOM元素的问题
2010/12/24 Javascript
JS验证控制输入中英文字节长度(input、textarea等)具体实例
2013/06/21 Javascript
Seajs的学习笔记
2014/03/04 Javascript
js日期范围初始化得到前一个月日期的方法
2015/05/05 Javascript
javascript正则表达式定义(语法)总结
2016/01/08 Javascript
快速掌握Node.js模块封装及使用
2016/03/21 Javascript
Angularjs中使用layDate日期控件示例
2017/01/11 Javascript
深入理解angular2启动项目步骤
2017/07/15 Javascript
修改 bootstrap table 默认detailRow样式的实例代码
2017/07/21 Javascript
详解Puppeteer 入门教程
2018/05/09 Javascript
浅谈React的最大亮点之虚拟DOM
2018/05/29 Javascript
前端axios下载excel文件(二进制)的处理方法
2018/07/31 Javascript
Angular动画实现的2种方式以及添加购物车动画实例代码
2018/08/09 Javascript
微信小程序indexOf的替换方法(推荐)
2020/01/14 Javascript
让python的Cookie.py模块支持冒号做key的方法
2010/12/28 Python
python元组操作实例解析
2014/09/23 Python
Python标准库之循环器(itertools)介绍
2014/11/25 Python
Python读取指定目录下指定后缀文件并保存为docx
2017/04/23 Python
python range()函数取反序遍历sequence的方法
2018/06/25 Python
深入了解python中元类的相关知识
2019/08/29 Python
python 读取数据库并绘图的实例
2019/12/03 Python
浅谈matplotlib.pyplot与axes的关系
2020/03/06 Python
Django 解决开发自定义抛出异常的问题
2020/05/21 Python
深入浅出CSS3 background-clip,background-origin和border-image教程
2011/01/27 HTML / CSS
Html5画布_动力节点Java学院整理
2017/07/13 HTML / CSS
2014年环保工作总结
2014/11/26 职场文书
质量保证书格式
2015/02/27 职场文书
CSS 一行代码实现头像与国旗的融合
2021/10/24 HTML / CSS
Go语言基础map用法及示例详解
2021/11/17 Golang
html粘性页脚的具体使用
2022/01/18 HTML / CSS