用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 null,undefined,字符串小结
Aug 21 Javascript
javascript正则表达式中参数g(全局)的作用
Nov 11 Javascript
JSDoc 介绍使用规范JsDoc的使用介绍
Feb 12 Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
May 17 Javascript
为指定的元素添加遮罩层的示例代码
Jan 15 Javascript
基于jQuery实现最基本的淡入淡出效果实例
Feb 02 Javascript
JS模拟酷狗音乐播放器收缩折叠关闭效果代码
Oct 29 Javascript
JavaScript学习笔记之函数记忆
Sep 06 Javascript
利用vue开发一个所谓的数独方法实例
Dec 21 Javascript
微信小程序云开发之云函数详解
May 16 Javascript
ES6中Symbol、Set和Map用法详解
Aug 20 Javascript
微信小程序选择图片控件
Jan 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
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
php漏洞之跨网站请求伪造与防止伪造方法
2013/08/15 PHP
php设置允许大文件上传示例代码
2014/03/10 PHP
PHP数组遍历的几种常见方式总结
2019/02/15 PHP
Js获取事件对象代码
2010/08/05 Javascript
jquery获取元素值的方法(常见的表单元素)
2013/11/15 Javascript
javascript 表格内容排序 简单操作示例代码
2014/01/03 Javascript
JavaScript-RegExp对象只能使用一次问题解决方法
2014/06/23 Javascript
JavaScript自定义等待wait函数实例分析
2015/03/23 Javascript
JavaScript基础知识点归纳(推荐)
2016/07/09 Javascript
最丑的时钟效果!js canvas时钟制作方法
2016/08/15 Javascript
JQuery 动态生成Table表格实例代码
2016/12/02 Javascript
微信小程序如何获知用户运行小程序的场景教程
2017/05/17 Javascript
JS沙箱模式实例分析
2017/09/04 Javascript
Vue通过URL传参如何控制全局console.log的开关详解
2017/12/07 Javascript
玩转vue的slot内容分发
2018/09/22 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
2020/06/16 Javascript
[02:08]什么藏在DOTA2 TI9“小紫本”里?斧王历险记告诉你!
2019/05/17 DOTA
如何实现Django Rest framework版本控制
2019/07/25 Python
python根据多个文件名批量查找文件
2019/08/13 Python
Python数据可视化处理库PyEcharts柱状图,饼图,线性图,词云图常用实例详解
2020/02/10 Python
在Mac中PyCharm配置python Anaconda环境过程图解
2020/03/11 Python
解决python调用自己文件函数/执行函数找不到包问题
2020/06/01 Python
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
Clarisonic美国官网:科莱丽声波洁面仪
2017/10/12 全球购物
Luxplus丹麦:香水和个人护理折扣
2018/04/23 全球购物
澳大利亚在线批发商:Simply Wholesale
2021/02/24 全球购物
风险评估实施方案
2014/03/09 职场文书
党的群众路线教育实践活动心得体会(医院)
2014/11/03 职场文书
2014年生产部工作总结
2014/12/17 职场文书
班主任自我评价范文
2015/03/11 职场文书
发票退票证明
2015/06/24 职场文书
祝酒词范文
2015/08/12 职场文书
运动会口号霸气押韵
2015/12/24 职场文书
制定企业培训计划的五大要点!
2019/07/10 职场文书
python绘制简单直方图(质量分布图)的方法
2022/04/21 Python