用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 相关文章推荐
div+css布局的图片连续滚动js实现代码
May 04 Javascript
Javascript实现真实字符串剩余字数提示的实例代码
Oct 22 Javascript
jquery自定义滚动条插件示例分享
Feb 21 Javascript
javascript实现网页子页面遍历回调的方法(涉及 window.frames、递归函数、函数上下文)
Jul 27 Javascript
JS模拟实现Select效果代码
Sep 24 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
Jan 08 Javascript
js实现input密码框提示信息的方法(附html5实现方法)
Jan 14 Javascript
浅析Javascript中bind()方法的使用与实现
Apr 29 Javascript
Javascript操作dom对象之select全面解析
Apr 24 Javascript
解决vue的变量在settimeout内部效果失效的问题
Aug 30 Javascript
在vue中利用全局路由钩子给url统一添加公共参数的例子
Nov 01 Javascript
原生JavaScript实现简单五子棋游戏
Jun 28 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初学者们头痛的十四个问题
2007/01/15 PHP
完整删除ecshop中获取店铺信息的API
2014/12/24 PHP
从阿里妈妈发现的几个不错的表单验证函数
2007/09/21 Javascript
JQuery的$和其它JS发生冲突的快速解决方法
2014/01/24 Javascript
判断某个字符在一个字符串中是否存在的js代码
2014/02/28 Javascript
jquery日历控件实现方法分享
2014/03/07 Javascript
WEB前端设计师常用工具集锦
2014/12/09 Javascript
js对象的复制继承实例
2015/01/10 Javascript
asp.net中oracle 存储过程(图文)
2015/08/12 Javascript
Javascript仿新浪游戏频道鼠标悬停显示子菜单效果
2015/08/21 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
2016/05/17 Javascript
easyui window refresh 刷新两次的解决方法(推荐)
2016/05/18 Javascript
Bootstrap页面标题Page Header的实现方法
2017/03/22 Javascript
Web前端框架Angular4.0.0 正式版发布
2017/03/28 Javascript
js使用i18n实现页面国际化的方法
2017/05/09 Javascript
基于react组件之间的参数传递(详解)
2017/09/05 Javascript
从对象列表中获取一个对象的方法,依据关键字和值
2017/09/20 Javascript
Node.js Stream ondata触发时机与顺序的探索
2019/03/08 Javascript
解决layer 动态加载select 失效的问题
2019/09/18 Javascript
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
vue+echarts实现中国地图流动效果(步骤详解)
2021/01/27 Vue.js
Python基础教程之内置函数locals()和globals()用法分析
2018/03/16 Python
python实现树形打印目录结构
2018/03/29 Python
Python封装成可带参数的EXE安装包实例
2019/08/24 Python
520使用Python实现“我爱你”表白
2020/05/20 Python
白宫黑市官网:White House Black Market
2016/11/17 全球购物
法学研究生自我鉴定范文
2013/12/04 职场文书
生日主持词
2014/03/20 职场文书
公司晚会策划方案
2014/05/17 职场文书
2014年电话客服工作总结
2014/12/09 职场文书
2015年数学教研组工作总结
2015/05/23 职场文书
甲午大海战观后感
2015/06/02 职场文书
新西兰:最新留学学习计划书写作指南
2019/07/15 职场文书
Java如何实现树的同构?
2021/06/22 Java/Android
springboot使用Redis作缓存使用入门教程
2021/07/25 Redis
Vue router配置与使用分析讲解
2022/12/24 Vue.js