用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入门指导
Nov 01 Javascript
php is_numberic函数造成的SQL注入漏洞
Mar 10 Javascript
js星星评分效果
Jul 24 Javascript
Node.js Addons翻译(C/C++扩展)
Jun 12 Javascript
js获取元素的标签名实现方法
Oct 08 Javascript
js滚轮事件兼容性问题需要注意哪些
Nov 15 Javascript
Bootstrap轮播图的使用和理解4
Dec 14 Javascript
js基于myFocus实现轮播图效果
Feb 14 Javascript
基于vue展开收起动画的示例代码
Jul 05 Javascript
Vue Autocomplete 自动完成功能简单示例
May 25 Javascript
微信小程序调用wx.getImageInfo遇到的坑解决
May 31 Javascript
vue2.0 解决抽取公用js的问题
Jul 31 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
探讨如何在php168_cms中提取验证码
2013/06/08 PHP
解析PHP 使用curl提交json格式数据
2013/06/29 PHP
PHP实现数组和对象的相互转换操作示例
2019/03/20 PHP
JavaScript模板入门介绍
2012/09/26 Javascript
javascript使用isNaN()函数判断变量是否为数字
2013/09/21 Javascript
深入理解javascript变量声明
2014/11/20 Javascript
10个JavaScript中易犯小错误
2016/02/14 Javascript
Javascript使用function创建类的两种方法(推荐)
2016/11/19 Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
2017/03/06 Javascript
Angularjs 实现动态添加控件功能
2017/05/25 Javascript
jquery学习笔记之无new构建详解
2017/12/07 jQuery
浅谈Vue.js中ref ($refs)用法举例总结
2017/12/19 Javascript
微信网页授权并获取用户信息的方法
2018/07/30 Javascript
一个小时快速搭建微信小程序的方法步骤
2019/04/15 Javascript
JavaScript JSON使用原理及注意事项
2020/07/30 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
2020/10/28 Javascript
Python的randrange()方法使用教程
2015/05/15 Python
Python通过poll实现异步IO的方法
2015/06/04 Python
使用Python读写文本文件及编写简单的文本编辑器
2016/03/11 Python
python检查URL是否正常访问的小技巧
2017/02/25 Python
python实现聊天小程序
2018/03/13 Python
python 列表递归求和、计数、求最大元素的实例
2018/11/28 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
2019/01/19 Python
创建Shapefile文件并写入数据的例子
2019/11/26 Python
Python将列表中的元素转化为数字并排序的示例
2019/12/25 Python
解决python-docx打包之后找不到default.docx的问题
2020/02/13 Python
python读取文件指定行内容实例讲解
2020/03/02 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
几款好用的python工具库(小结)
2020/10/20 Python
CSS3 Flex 弹性布局实例代码详解
2018/11/01 HTML / CSS
EJB的基本架构
2016/09/22 面试题
HttpServlet类中的主要方法都有哪些?各自的作用是什么?
2014/03/16 面试题
四年大学生活的个人自我评价
2013/12/11 职场文书
50岁生日感言
2014/01/23 职场文书
员工考勤管理制度
2015/08/06 职场文书
Vue+Element UI实现概要小弹窗的全过程
2021/05/30 Vue.js