用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 相关文章推荐
js checkbox(复选框) 使用集锦
Apr 28 Javascript
JavaScript Array扩展实现代码
Oct 14 Javascript
SWFObject 2.1以上版本语法介绍
Jul 10 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
Apr 11 Javascript
jquery.post用法示例代码
Jan 03 Javascript
JavaScript中的this机制
Jan 30 Javascript
基于jQuery实现select下拉选择可输入附源码下载
Feb 03 Javascript
Vue2路由动画效果的实现代码
Jul 10 Javascript
js 两数组去除重复数值的实例
Dec 06 Javascript
webpack打包非模块化js的方法
Oct 24 Javascript
微信小程序自定义toast的实现代码
Nov 16 Javascript
JS apply用法总结和使用场景实例分析
Mar 14 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 print EOF实现方法
2009/05/21 PHP
提高PHP编程效率 引入缓存机制提升性能
2010/02/15 PHP
AMFPHP php远程调用(RPC, Remote Procedure Call)工具 快速入门教程
2010/05/10 PHP
PHP中将网页导出为Word文档的代码
2012/05/25 PHP
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
Windows和Linux中php代码调试工具Xdebug的安装与配置详解
2014/05/08 PHP
详解PHP中websocket的使用方法
2016/09/15 PHP
php简单构造json多维数组的方法示例
2017/06/08 PHP
laravel 如何实现引入自己的函数或类库
2019/10/15 PHP
javascript 简练的几个函数
2009/08/29 Javascript
手机开发必备技巧:javascript及CSS功能代码分享
2015/05/25 Javascript
Dojo获取下拉框的文本和值实例代码
2016/05/27 Javascript
基于jQuery的checkbox全选问题分析
2016/11/18 Javascript
webpack教程之webpack.config.js配置文件
2017/07/05 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
2018/01/06 jQuery
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
解决vue的touchStart事件及click事件冲突问题
2020/07/21 Javascript
如何实现vue的tree组件
2020/12/03 Vue.js
[04:32]DOTA2著名解说配音敌法师 现场专访海涛怒切假腿
2013/12/20 DOTA
python正则表达式去掉数字中的逗号(python正则匹配逗号)
2013/12/25 Python
python中字符串类型json操作的注意事项
2017/05/02 Python
Python虚拟环境virtualenv的安装与使用详解
2017/05/28 Python
解决win64 Python下安装PIL出错问题(图解)
2018/09/03 Python
修改python plot折线图的坐标轴刻度方法
2018/12/13 Python
python实现动态数组的示例代码
2019/07/15 Python
如何在Python对Excel进行读取
2020/06/04 Python
写出程序把一个链表中的接点顺序倒排
2014/04/28 面试题
汽车电子与维修专业大学生求职信
2013/09/28 职场文书
《夏夜多美》教学反思
2014/02/17 职场文书
大学生个人自荐信
2014/02/24 职场文书
教师师德承诺书
2014/03/26 职场文书
党校学习心得体会范文
2014/09/09 职场文书
党员干部群众路线个人整改措施
2014/09/18 职场文书
三严三实心得体会范文
2014/10/13 职场文书
Pandas-DataFrame知识点汇总
2022/03/16 Python
mysql如何查询连续记录
2022/05/11 MySQL