用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跨域和ajax 跨域问题的实现思路
Sep 05 Javascript
javascript中IE浏览器不支持NEW DATE()带参数的解决方法
Mar 01 Javascript
使用非html5实现js板连连看游戏示例代码
Sep 22 Javascript
js将json格式的对象拼接成复杂的url参数方法
May 25 Javascript
Node.js实现文件上传
Jul 05 Javascript
canvas滤镜效果实现代码
Feb 06 Javascript
详解AngularJs ui-router 路由的简单介绍
Apr 26 Javascript
vue实现动态添加数据滚动条自动滚动到底部的示例代码
Jul 06 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
Jan 18 jQuery
vue实现搜索功能
May 28 Javascript
vue(2.x,3.0)配置跨域代理
Nov 27 Javascript
JavaScript setInterval()与setTimeout()计时器
Dec 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
AngularJS转换响应内容
Jan 27 #Javascript
You might like
虫族 Zerg 热键控制
2020/03/14 星际争霸
PHP下编码转换函数mb_convert_encoding与iconv的使用说明
2009/12/16 PHP
自己动手制作jquery插件之自动添加删除行功能介绍
2011/10/14 Javascript
JS获取URL中的参数数据
2013/12/05 Javascript
js 上下左右键控制焦点(示例代码)
2013/12/14 Javascript
Javascript中的异步编程规范Promises/A详细介绍
2014/06/06 Javascript
jQuery使用load()方法载入另外一个网页文件内的指定标签内容到div标签的方法
2015/03/25 Javascript
noty ? jQuery通知插件全面解析
2016/05/18 Javascript
Bootstrap+jfinal实现省市级联下拉菜单
2016/05/30 Javascript
详解Angular.js中$http拦截器的介绍及使用
2017/07/04 Javascript
使用react-router4.0实现重定向和404功能的方法
2017/08/28 Javascript
在Swiper内如何制作CSS3动画效果示例代码
2017/12/07 Javascript
使用vue中的v-for遍历二维数组的方法
2018/03/07 Javascript
微信小程序登录按钮遮罩浮层效果的实现方法
2018/12/16 Javascript
如何基于原生javaScript生成带图片的二维码
2019/11/21 Javascript
解决VUE项目使用Element-ui 下拉组件的验证失效问题
2020/11/07 Javascript
[01:10]DOTA2次级职业联赛 - U5战队宣传片
2014/12/01 DOTA
python self,cls,decorator的理解
2009/07/13 Python
Python装饰器的函数式编程详解
2015/02/27 Python
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
python 异常处理总结
2016/10/18 Python
Python如何实现守护进程的方法示例
2017/02/08 Python
python中 chr unichr ord函数的实例详解
2017/08/06 Python
使用python爬虫实现网络股票信息爬取的demo
2018/01/05 Python
python学习入门细节知识点
2018/03/29 Python
对Python中Iterator和Iterable的区别详解
2018/10/18 Python
python读取并写入mat文件的方法
2019/07/12 Python
Python导入数值型Excel数据并生成矩阵操作
2020/06/09 Python
Python3读写ini配置文件的示例
2020/11/06 Python
初探CSS3中的calc()功能
2015/07/14 HTML / CSS
总结30个CSS3选择器
2017/04/13 HTML / CSS
应届毕业生求职信
2014/05/26 职场文书
土建技术员岗位职责
2015/04/11 职场文书
防溺水主题班会教案
2015/08/12 职场文书
2016父亲节感恩话语
2015/12/09 职场文书
Python 发送SMTP邮件的简单教程
2021/06/24 Python