用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 相关文章推荐
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
Dec 02 Javascript
JavaScript 嵌套函数指向this对象错误的解决方法
Mar 15 Javascript
关于IE浏览器以及Firefox下的javascript冒泡事件的响应层级
Oct 14 Javascript
jQuery弹性滑动导航菜单实现思路及代码
May 02 Javascript
jQuery中index()方法用法实例
Dec 27 Javascript
深入理解JavaScript系列(48):对象创建模式(下篇)
Mar 04 Javascript
Angularjs在初始化未完毕时出现闪烁问题的解决方法分析
Aug 05 Javascript
BootStrap轻松实现微信页面开发代码分享
Oct 21 Javascript
微信小程序倒计时功能实例代码
Jul 17 Javascript
微信小程序中悬浮窗功能的实现代码
Aug 02 Javascript
基于JavaScript获取url参数2种方法
Apr 17 Javascript
js定时器出现第一次延迟的原因及解决方法
Jan 04 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修改密码方法总结
2008/03/25 PHP
phpmyadmin 3.4 空密码登录的实现方法
2010/05/29 PHP
PHP程序员常见的40个陋习,你中了几个?
2014/11/20 PHP
做网页的一些技巧(续)
2007/02/01 Javascript
onclick与listeners的执行先后问题详细解剖
2013/01/07 Javascript
超级简单的jquery操作表格方法
2014/12/15 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
2015/02/20 Javascript
js游戏人物上下左右跑步效果代码分享
2015/08/28 Javascript
jquery获取url参数及url加参数的方法
2015/10/26 Javascript
JavaScript计算值然后把值嵌入到html中的实现方法
2016/10/29 Javascript
JavaScript的六种继承方式(推荐)
2017/06/26 Javascript
canvas轨迹回放功能实现
2017/12/20 Javascript
详解如何使用微信小程序云函数发送短信验证码
2019/03/13 Javascript
VUE接入腾讯验证码功能(滑块验证)备忘
2019/05/07 Javascript
layui清空,重置表单数据的实例
2019/09/12 Javascript
webpack4 配置 ssr 环境遇到“document is not defined”
2019/10/24 Javascript
[02:35]DOTA2英雄基础教程 末日使者
2013/12/04 DOTA
[14:50]2018DOTA2亚洲邀请赛开幕式
2018/04/03 DOTA
python 解析XML python模块xml.dom解析xml实例代码
2014/02/07 Python
python实现忽略大小写对字符串列表排序的方法
2014/09/25 Python
Python中的包和模块实例
2014/11/22 Python
Python装饰器使用示例及实际应用例子
2015/03/06 Python
深入源码解析Python中的对象与类型
2015/12/11 Python
通过Python使用saltstack生成服务器资产清单
2016/03/01 Python
Python中动态创建类实例的方法
2017/03/24 Python
Linux下多个Python版本安装教程
2018/08/15 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
2019/01/22 Python
python3利用Socket实现通信的方法示例
2019/05/06 Python
Python将文字转成语音并读出来的实例详解
2019/07/15 Python
python nmap实现端口扫描器教程
2020/05/28 Python
python如何操作mysql
2020/08/17 Python
英国银首饰公司:e&e Jewellery
2021/02/11 全球购物
护士专业推荐信
2013/11/02 职场文书
2015年毕业生自荐信范文
2015/03/24 职场文书
2016年“六一儿童节”校园广播稿
2015/12/17 职场文书
Python如何用re模块实现简易tokenizer
2022/05/02 Python