用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 应用类库代码
Jun 02 Javascript
jQuery(非HTML5)可编辑表格实现代码
Dec 11 Javascript
热点新闻滚动特效的js代码
Aug 17 Javascript
jquery实现checkbox 全选/全不选的通用写法
Feb 22 Javascript
js表格排序实例分析(支持int,float,date,string四种数据类型)
May 06 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
May 27 Javascript
基于jQuery实现咖啡订单管理简单应用
Feb 10 Javascript
bootstrap multiselect 多选功能实现方法
Jun 05 Javascript
深入理解vue-loader如何使用
Jun 06 Javascript
客户端(vue框架)与服务器(koa框架)通信及服务器跨域配置详解
Aug 26 Javascript
解决js ajax同步请求造成浏览器假死的问题
Jan 18 Javascript
简述vue路由打开一个新的窗口的方法
Nov 29 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 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
使用Zttp简化Guzzle 调用
2017/07/02 PHP
Yii2.0框架模型多表关联查询示例
2019/07/18 PHP
laravel框架模型、视图与控制器简单操作示例
2019/10/10 PHP
PHP如何通过date() 函数格式化显示时间
2020/11/13 PHP
php的lavarel框架中join和orWhere的用法
2020/12/28 PHP
javascript学习笔记(十七) 检测浏览器插件代码
2012/06/20 Javascript
JavaScript中的small()方法使用详解
2015/06/08 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
2016/12/19 Javascript
初探nodeJS
2017/01/24 NodeJs
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
Vue Ajax跨域请求实例详解
2017/06/20 Javascript
微信小程序swiper禁止用户手动滑动代码实例
2019/08/23 Javascript
jQuery+ThinkPHP实现图片上传
2020/07/23 jQuery
在Python下利用OpenCV来旋转图像的教程
2015/04/16 Python
Python实现登录人人网并抓取新鲜事的方法
2015/05/11 Python
Python实现的概率分布运算操作示例
2017/08/14 Python
Python 多核并行计算的示例代码
2017/11/07 Python
python实现名片管理系统
2018/11/29 Python
详解Python中list[::-1]的几种用法
2020/11/16 Python
俄罗斯的精英皮具:Wittchen
2018/01/29 全球购物
俄罗斯首家面向中国消费者的一站式购物网站:Wruru
2020/05/08 全球购物
用你熟悉的语言写一个连接ORACLE数据库的程序,能够完成修改和查询工作
2012/06/11 面试题
C#如何调用Windows程序打开一个文档
2014/12/26 面试题
建筑装饰学院室内设计专业个人自我评价
2013/12/07 职场文书
竞选班长的演讲稿
2014/04/24 职场文书
实习生评语
2014/04/26 职场文书
关于读书的演讲稿1000字
2014/08/27 职场文书
交通事故和解协议书
2014/09/25 职场文书
离婚协议书应该怎么写
2014/10/12 职场文书
送给教师们,到底该如何写好教学反思?
2019/07/02 职场文书
Python中os模块的简单使用及重命名操作
2021/04/17 Python
python 提取html文本的方法
2021/05/20 Python
vue代码分块和懒加载非必要资源文件
2022/04/11 Vue.js