用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评估用户输入密码的强度(Knockout版)
Nov 30 Javascript
js实现身份证号码验证的简单实例
Feb 19 Javascript
javascript面向对象之定义成员方法实例分析
Jan 13 Javascript
js中跨域方法原理详解
Jul 19 Javascript
Knockoutjs 学习系列(一)ko初体验
Jun 07 Javascript
JQuery ZTree使用方法详解
Jan 07 Javascript
vue.js 左侧二级菜单显示与隐藏切换的实例代码
May 23 Javascript
JS使用对象的defineProperty进行变量监控操作示例
Feb 02 Javascript
详解Vue demo实现商品列表的展示
May 07 Javascript
使vue实现jQuery调用的两种方法
May 12 jQuery
vue仿ios列表左划删除
Sep 26 Javascript
js实现表单项的全选、反选及删除操作示例
Jun 05 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连mysql和oracle数据库性能比较
2006/10/09 PHP
使用pthreads实现真正的PHP多线程(需PHP5.3以上版本)
2014/05/05 PHP
php实现插入排序
2015/03/29 PHP
PHP第三方登录―QQ登录实现方法
2017/02/06 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
2017/10/22 PHP
DHTML 中的绝对定位
2006/11/26 Javascript
javascript 出生日期和身份证判断大全
2008/11/13 Javascript
Iframe自适应高度绝对好使的代码 兼容IE,遨游,火狐
2011/01/27 Javascript
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
Extjs TimeField 显示正常时间格式的代码
2011/06/28 Javascript
加载 Javascript 最佳实践
2011/10/30 Javascript
JavaScript实现简单的数字倒计时
2015/05/15 Javascript
JavaScript学习小结(一)——JavaScript入门基础
2015/09/02 Javascript
jquery radio的取值_radio的选中_radio的重置方法
2016/09/20 Javascript
Javascript 调用 ActionScript 的简单方法
2016/09/22 Javascript
AngularJS  双向数据绑定详解简单实例
2016/10/20 Javascript
javascript实现无法关闭的弹框
2016/11/27 Javascript
vue中axios的封装问题(简易版拦截,get,post)
2018/06/15 Javascript
微信小程序云开发 搭建一个管理小程序
2019/05/17 Javascript
前端Electron新手入门教程详解
2019/06/21 Javascript
Vue使用mixin分发组件的可复用功能
2019/09/01 Javascript
vue-cli —— 如何局部修改Element样式
2020/10/22 Javascript
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
利用Python批量提取Win10锁屏壁纸实战教程
2018/03/27 Python
Pythony运维入门之Socket网络编程详解
2019/04/15 Python
django rest framework vue 实现用户登录详解
2019/07/29 Python
Python创建数字列表的示例
2019/11/28 Python
Python数据持久化存储实现方法分析
2019/12/21 Python
带有css3动画效果的兼容多浏览器简单导航条示例
2014/01/26 HTML / CSS
领导证婚人证婚词
2014/01/13 职场文书
工作表现自我评价
2014/02/08 职场文书
低碳生活的宣传标语
2014/06/23 职场文书
国际商务英语专业求职信
2014/07/08 职场文书
驻村工作先进事迹
2014/08/14 职场文书
试用期自我评价范文
2015/03/10 职场文书
2016年小学生寒假总结
2015/10/10 职场文书