用window.onerror捕获并上报Js错误的方法


Posted in Javascript onJanuary 27, 2016

前两天有个2048游戏的用户反馈说,打开游戏后不能玩儿,只有一个游戏面板,数字无法初始化,更无法移动,设备为iPhone 4S、iOS 5.1。尝试从微信调起Safari打开,依然不好使。由于游戏中运用了比较多的HTML5特性,所以粗略估计是有JS报错导致。不过这样的信息该如何捕获到呢?当然是传说中的window.onerror。

从W3C找到关于window.onerror的方法体介绍:

用window.onerror捕获并上报Js错误的方法

这个意思,基本可以就是说,window.onerror方法,我们可以写成:

/** 
 * @param {String} errorMessage  错误信息 
 * @param {String} scriptURI   出错的文件 
 * @param {Long}  lineNumber   出错代码的行号 
 * @param {Long}  columnNumber  出错代码的列号 
 * @param {Object} errorObj    错误的详细信息,Anything 
 */
window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { 
  // TODO 
}

不过使用过程中还得注意兼容性问题,不是所有浏览器都有参数列表中的所有参数,chrome之类的,都是浏览器标准草案的领跑者,这些个参数用就是了!

于是,可以写一个小Demo来尝试一下:

<!DOCTYPE html> 
<html> 
<head> 
  <title>Js错误捕获</title> 
  <script type="text/javascript"> 
  /** 
   * @param {String} errorMessage  错误信息 
   * @param {String} scriptURI   出错的文件 
   * @param {Long}  lineNumber   出错代码的行号 
   * @param {Long}  columnNumber  出错代码的列号 
   * @param {Object} errorObj    错误的详细信息,Anything 
   */ 
  window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { 
    console.log("错误信息:" , errorMessage); 
    console.log("出错文件:" , scriptURI); 
    console.log("出错行号:" , lineNumber); 
    console.log("出错列号:" , columnNumber); 
    console.log("错误详情:" , errorObj); 
  } 
  </script> 
</head> 
<body> 
  <script type="text/javascript" src="error.js"></script> 
</body> 
</html>

其中error.js文件中的内容,简单的这样写一句:

throw new Error("出错了!");
用浏览器跑起来以后,打开console,基本就是这样的了:

用window.onerror捕获并上报Js错误的方法

所以,这些数据都是可以做上报的了。
当然了,上面的error.js是和html页面同域名下,如果error.js不在同域下,会是怎样的?我们把error.js的引用改一下:

<script type="text/javascript" src="//doitbegin.duapp.com/error.js"></script>
再来打开console,我们看到的是这样的:

用window.onerror捕获并上报Js错误的方法

相当于window.onerror方法只捕获到了一个errorMessage,而且是固定字符串,毫无参考价值。查了点资料(Webkit源码),发现在浏览器实现script资源加载的地方,是进行了同源策略判断的,如果是非同源资源,errorMessage就被写死为“Script error”了:

用window.onerror捕获并上报Js错误的方法

好在script标签有一个crossorigin属性,设置它可以显示比较详细的错误信息,我们试着将script标签改一下:

<script type="text/javascript" src="//doitbegin.duapp.com/error.js" crossorigin></script>
刷新页面,这个时候看到console中的输出是这样的:

用window.onerror捕获并上报Js错误的方法

出现这个error也不意外,既然设置了error.js为crossorigin,那error.js的HTTP Response Header也必须设置非同源可访问。为了方便设置Header,把error.js做一个小改动,更名为:error-js.php。

<?php 
  header('Access-Control-Allow-Origin:*'); 
  header('Content-type:text/javascript'); 
?> 
throw new Error('出错了');

此时刷新页面,看到console中的输出就已经正常了,所有信息都能正常捕获:

用window.onerror捕获并上报Js错误的方法

OK,技术细节分析结束!我2048游戏静态资源是放到静态域(非同源)下的,所以要想通过window.onerror捕获错误信息,就得按照上面的最后一种情况来操作了:

1、添加script的crossorigin属性

2、配置一下服务器,设置静态资源Javascript的Response为Access-Control-Allow-Origin

Javascript 相关文章推荐
javascript mouseover、mouseout停止事件冒泡的解决方案
Apr 07 Javascript
js中根据字数截取字符串,不能截断url
Jan 12 Javascript
Firefox和IE兼容性问题及解决方法总结
Oct 08 Javascript
纯JavaScript实现的分页插件实例
Jul 14 Javascript
JavaScript实现上下浮动的窗口效果代码
Oct 12 Javascript
AngularJS 日期格式化详解
Dec 23 Javascript
jQuery插件zTree实现清空选中第一个节点所有子节点的方法
Mar 08 Javascript
JS实现去除数组中重复json的方法示例
Dec 21 Javascript
React实现全局组件的Toast轻提示效果
Sep 21 Javascript
BootStrap模态框闪退问题实例代码详解
Dec 10 Javascript
js实现贪吃蛇小游戏
Oct 29 Javascript
JavaScript 绘制饼图的示例
Feb 19 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
AngularJS转换响应内容
Jan 27 #Javascript
You might like
PHP操作xml代码
2010/06/17 PHP
php自定义urlencode,urldecode函数实例
2015/03/24 PHP
php中的常用魔术方法汇总
2016/02/14 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
php文件后缀不强制为.php的实操方法
2019/09/18 PHP
JavaScript中SQL语句的应用实现
2010/05/04 Javascript
javascript学习笔记(十九) 节点的操作实现代码
2012/06/20 Javascript
JavaScript link方法入门实例(给字符串加上超链接)
2014/10/17 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
JavaScript必知必会(七)js对象继承
2016/06/08 Javascript
JavaScript中利用构造器函数模拟类的方法
2017/02/16 Javascript
nodejs集成sqlite使用示例
2017/06/05 NodeJs
vue中实现图片和文件上传的示例代码
2018/03/16 Javascript
AngularJS ui-router刷新子页面路由的方法
2018/07/23 Javascript
详解Vue2.0组件的继承与扩展
2018/11/23 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
用JS实现一个简单的打砖块游戏
2019/12/11 Javascript
Nodejs实现微信分账的示例代码
2021/01/19 NodeJs
Python实现查找二叉搜索树第k大的节点功能示例
2019/01/24 Python
Django框架中间件(Middleware)用法实例分析
2019/05/24 Python
通过python实现弹窗广告拦截过程详解
2019/07/10 Python
django的分页器Paginator 从django中导入类
2019/07/25 Python
Python3 pickle对象串行化代码实例解析
2020/03/23 Python
CSS3实现精美横向滚动菜单按钮
2017/04/14 HTML / CSS
澳大利亚最好的厨具店:Kitchen Warehouse
2018/03/13 全球购物
神话般的珠宝:Ross-Simons
2020/07/13 全球购物
初中音乐教学反思
2014/01/12 职场文书
交通志愿者活动总结
2014/06/27 职场文书
2014年新农村建设工作总结
2014/12/01 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
中国汉字听写大会观后感
2015/06/02 职场文书
子女赡养老人协议书
2016/03/23 职场文书
2019年大学生职业生涯规划书
2019/03/25 职场文书
如何使用Maxwell实时同步mysql数据
2021/04/08 MySQL
HTML5+CSS+JavaScript实现捉虫小游戏设计和实现
2021/10/16 HTML / CSS
《勇者辞职不干了》ED主题曲无字幕动画MV公开
2022/04/13 日漫