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 相关文章推荐
Jsonp 跨域的原理以及Jquery的解决方案
Jun 27 Javascript
javascript date格式化示例
Sep 25 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
Feb 12 Javascript
MVVM模式中ViewModel和View、Model有什么区别?
Jun 19 Javascript
jQuery实现鼠标双击Table单元格变成文本框及输入内容后更新到数据库的方法
Nov 25 Javascript
JavaScript新增样式规则(推荐)
Jul 19 Javascript
JavaScript 闭包详细介绍
Sep 28 Javascript
通过学习bootstrop导航条学会修改bootstrop颜色基调
Jun 11 Javascript
关于Vue单页面骨架屏实践记录
Dec 13 Javascript
webpack中的热刷新与热加载的区别
Apr 09 Javascript
vue-baidu-map 进入页面自动定位的解决方案(推荐)
Apr 28 Javascript
vue axios基于常见业务场景的二次封装的实现
Sep 21 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初学者的8点有效建议
2010/11/20 PHP
PHP7之Mongodb API使用详解
2015/12/26 PHP
PHP PDOStatement::setFetchMode讲解
2019/02/03 PHP
laravel实现上传图片并在页面显示的例子
2019/10/14 PHP
Javascript笔记一 js以及json基础使用说明
2010/05/22 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
2013/11/19 Javascript
JavaScript删除指定子元素代码实例
2015/01/13 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
2015/03/14 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
2015/08/22 Javascript
Jquery Mobile 自定义按钮图标
2015/11/18 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
动态加载js文件简单示例
2016/04/21 Javascript
小程序开发实战:实现九宫格界面的导航的代码实现
2017/01/19 Javascript
ES6中Proxy与Reflect实现重载(overload)的方法
2017/03/30 Javascript
AngularJS 前台分页实现的示例代码
2018/06/07 Javascript
bootstrap下拉分页样式 带跳转页码
2018/12/29 Javascript
jQuery实现input输入框获取焦点与失去焦点时提示的消失与显示功能示例
2019/05/27 jQuery
微信小程序实现点击空白隐藏的方法示例
2019/08/13 Javascript
js实现图片跟随鼠标移动效果
2019/10/16 Javascript
基于JS实现table导出Excel并保留样式
2020/05/19 Javascript
Python中几种操作字符串的方法的介绍
2015/04/09 Python
基于python中pygame模块的Linux下安装过程(详解)
2017/11/09 Python
TensorFlow实现简单卷积神经网络
2018/05/24 Python
Python设计模式之适配器模式原理与用法详解
2019/01/15 Python
对pyqt5多线程正确的开启姿势详解
2019/06/14 Python
python替换字符串中的子串图文步骤
2019/06/19 Python
python UDP(udp)协议发送和接收的实例
2019/07/22 Python
Python CSV文件模块的使用案例分析
2019/12/21 Python
keras 自定义loss model.add_loss的使用详解
2020/06/22 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
销售总监工作职责
2013/11/21 职场文书
任命书范本大全
2014/06/06 职场文书
家装业务员岗位职责
2015/04/03 职场文书
文化苦旅读书笔记
2015/06/29 职场文书
Nginx设置日志打印post请求参数的方法
2021/03/31 Servers
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle