ld-embed
Version:
Web exception moniter
1,254 lines (1,053 loc) • 38.8 kB
JavaScript
/*!
* Copyright (c) 2021 Akira0705 <1225658998@qq.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.LdEmbed = factory());
}(this, (function () { 'use strict';
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
/* eslint-disable spaced-comment */
/* eslint-disable space-before-function-paren */
/* eslint-disable quotes */
// 屏幕分辨率
var utils = {
// 获取 系统 浏览器等相关信息
getBaseInfo: function getBaseInfo() {
// 获取屏幕信息
var screenInfo = this.getScreen();
screenInfo = Object.assign({}, screenInfo, {
colorDepth: this.getcolorDepth(),
pixelDepth: this.getPixelDepth()
});
var languageInfo = Object.assign({}, {
language: this.getLanguage()
});
var getSysInfo = this.getSysInfo();
var agentInfo = {
agent: this.getAgent(),
url: this.getLocalUrl(),
online: this.getNetStatus()
};
var envInfo = this.getEnv();
var ret = Object.assign({}, screenInfo, languageInfo, getSysInfo, agentInfo, envInfo);
return ret;
},
getEnv: function getEnv() {
var envInfo = {
env: "pro"
};
var domain = document.domain;
var arr = domain.split(".");
if (arr.length < 1) {
return envInfo;
}
if (domain === "127.0.0.1" || domain === "localhost" || arr[0].indexOf("dev") != -1) {
// 开发环境
envInfo.env = "dev";
}
if (arr[0].indexOf("test") != -1) {
// 测试环境禁用
envInfo.env = "test";
}
if (arr[0].indexOf("pre") != -1) {
// 预发布环境禁用
envInfo.env = "pre";
}
return envInfo;
},
getScreen: function getScreen() {
// var screen = {};
var clientWidth = document.body.clientWidth;
var clientHeight = document.body.clientHeight;
var availWidth = window.screen.availWidth;
var availHeight = window.screen.availHeight;
var width = window.screen.width;
var height = window.screen.height;
var myScreen = {
screenInfo: JSON.stringify({
clientWidth: clientWidth,
clientHeight: clientHeight,
availWidth: availWidth,
availHeight: availHeight
}),
width: width,
height: height
}; // myScreen.clientWidth = clientWidth;
// myScreen.clientHeight = clientHeight;
return myScreen;
},
// 函数可对字符串进行编码,防止中文乱码
encodeURI: function (_encodeURI) {
function encodeURI(_x) {
return _encodeURI.apply(this, arguments);
}
encodeURI.toString = function () {
return _encodeURI.toString();
};
return encodeURI;
}(function (str) {
// 进行URL编码
return encodeURI(str);
}),
// 颜色质量 色彩深度
getcolorDepth: function getcolorDepth() {
var c = "";
if (self.screen) {
c = screen.colorDepth + "-bit";
}
return c;
},
// screen.pixelDepth 像素深度
getPixelDepth: function getPixelDepth() {
var c = "";
if (self.screen) {
c = screen.pixelDepth + "-bit";
}
return c;
},
// 返回当前的浏览器语言
getLanguage: function getLanguage() {
var l = "";
var n = navigator;
if (n.language) {
l = n.language.toLowerCase();
} else if (n.browserLanguage) {
l = n.browserLanguage.toLowerCase();
}
return l;
},
// 获取浏览器设置语言首选项 真正应用的浏览器语言
getFirstLanguage: function getFirstLanguage() {},
// 返回浏览器类型IE,Firefox
getAgent: function getAgent() {
var a = "";
var n = navigator;
if (n.userAgent) {
a = n.userAgent;
}
return a;
},
// 返回客户端时间
getTime: function getTime() {
return new Date().getTime();
},
// 获取当前页面URL
getLocalUrl: function getLocalUrl() {
return window.location.href;
},
// 获取上一次页面URL
getLastUrl: function getLastUrl() {
return document.referrer;
},
// 获取上一个路由信息
getLastRoute: function getLastRoute() {},
// 获取网络状态 true / false
getNetStatus: function getNetStatus() {
// var connection = navigator.connection ||
// navigator.mozConnection ||
// navigator.webkitConnection || { tyep: "unknown" };
// console.log(connection);
// var typeText = ["unknown", "ethernet", "wifi", "2g", "3g", "4g", "none"];
// if (typeof connection.type == "number") {
// connection.typeText = typeText[connection.type];
// } else {
// connection.typeText = connection.type || connection.effectiveType;
// }
// if (typeof connection.downlink == "number") {
// if (connection.downlink > 10) {
// connection.type = "wifi";
// } else if (connection.downlink > 2) {
// connection.type = "3g";
// } else if (connection.downlink > 0) {
// connection.type = "2g";
// } else if (connection.downlink == 0) {
// connection.type = "none";
// } else {
// connection.type = "unknown";
// }
// }
// var html = "Type: " + connection.typeText;
// html += " Downlink: " + connection.downlink;
// html += " isOnline: " + navigator.onLine;
return navigator.onLine;
},
// 获取系统信息
getSysInfo: function getSysInfo() {
var sysInfo = {};
var browser = this.getBrowser() ? this.getBrowser().browser || "未知浏览器" : "未知浏览器"; //获取浏览器名
var version = this.getBrowser() ? this.getBrowser().version || "未知浏览器版本号" : "未知浏览器版本号"; //获取浏览器版本
var OS = this.getOS() + " " + this.getDigits() || "未知操作系统"; //系统版本号
sysInfo.browser = browser;
sysInfo.coreVersion = version;
sysInfo.OS = OS;
return sysInfo;
},
getOS: function getOS() {
//判断所处操作系统
var sUserAgent = navigator.userAgent.toLowerCase();
var isWin = navigator.platform == "Win32" || navigator.platform == "Win64" || navigator.platform == "wow64";
var isMac = navigator.platform == "Mac68K" || navigator.platform == "MacPPC" || navigator.platform == "Macintosh" || navigator.platform == "MacIntel";
if (isMac) return "Mac";
var isUnix = navigator.platform == "X11" && !isWin && !isMac;
if (isUnix) return "Unix";
var isLinux = String(navigator.platform).indexOf("Linux") > -1;
var bIsAndroid = sUserAgent.toLowerCase().match(/android/i) == "android";
if (isLinux) {
if (bIsAndroid) return "Android";else return "Linux";
}
if (isWin) {
var isWin2K = sUserAgent.indexOf("windows nt 5.0") > -1 || sUserAgent.indexOf("windows 2000") > -1;
if (isWin2K) return "Win2000";
var isWinXP = sUserAgent.indexOf("windows nt 5.1") > -1 || sUserAgent.indexOf("windows XP") > -1;
if (isWinXP) return "WinXP";
var isWin2003 = sUserAgent.indexOf("windows nt 5.2") > -1 || sUserAgent.indexOf("windows 2003") > -1;
if (isWin2003) return "Win2003";
var isWinVista = sUserAgent.indexOf("windows nt 6.0") > -1 || sUserAgent.indexOf("windows vista") > -1;
if (isWinVista) return "WinVista";
var isWin7 = sUserAgent.indexOf("windows nt 6.1") > -1 || sUserAgent.indexOf("windows 7") > -1;
if (isWin7) return "Win7";
var isWin8 = sUserAgent.indexOf("windows nt 6.2") > -1 || sUserAgent.indexOf("windows nt 6.3") > -1 || sUserAgent.indexOf("windows 8") > -1;
if (isWin8) return "Win8";
var isWin10 = sUserAgent.indexOf("windows nt 10.0") > -1 || sUserAgent.indexOf("windows 10") > -1;
if (isWin10) return "Win10";
return "Win";
}
return "其他";
},
getDigits: function getDigits() {
//判断当前操作系统的版本号
var sUserAgent = navigator.userAgent.toLowerCase();
var is64 = sUserAgent.indexOf("win64") > -1 || sUserAgent.indexOf("wow64") > -1;
if (is64) {
return "64位";
} else {
return "32位";
}
},
getBrowser: function getBrowser() {
// 获取浏览器名
// eslint-disable-next-line no-useless-escape
var rMsie = /(msie\s|trident\/7)([\w\.]+)/;
var rTrident = /(trident)\/([\w.]+)/;
var rEdge = /(chrome)\/([\w.]+)/; // IE
var rFirefox = /(firefox)\/([\w.]+)/; // 火狐
var rOpera = /(opera).+version\/([\w.]+)/; // 旧Opera
var rNewOpera = /(opr)\/(.+)/; // 新Opera 基于谷歌
var rChrome = /(chrome)\/([\w.]+)/; // 谷歌
var rUC = /(chrome)\/([\w.]+)/; // UC
var rMaxthon = /(chrome)\/([\w.]+)/; // 遨游
var r2345 = /(chrome)\/([\w.]+)/; // 2345
var rQQ = /(chrome)\/([\w.]+)/; // QQ
// var rMetasr = /(metasr)\/([\w.]+)/;//搜狗
var rSafari = /version\/([\w.]+).*(safari)/;
var ua = navigator.userAgent.toLowerCase();
var matchBS, matchBS2; // IE 低版
matchBS = rMsie.exec(ua);
if (matchBS != null) {
matchBS2 = rTrident.exec(ua);
if (matchBS2 != null) {
switch (matchBS2[2]) {
case "4.0":
return {
browser: "Microsoft IE",
version: "IE: 8" //内核版本号
};
// break;
case "5.0":
return {
browser: "Microsoft IE",
version: "IE: 9"
};
// break;
case "6.0":
return {
browser: "Microsoft IE",
version: "IE: 10"
};
// break;
case "7.0":
return {
browser: "Microsoft IE",
version: "IE: 11"
};
// break;
default:
return {
browser: "Microsoft IE",
version: "Undefined"
};
}
} else {
return {
browser: "Microsoft IE",
version: "IE:" + matchBS[2] || "0"
};
}
} //谷歌浏览器
matchBS = rChrome.exec(ua);
if (matchBS != null && !window.attachEvent) {
matchBS2 = rNewOpera.exec(ua);
if (matchBS2 == null) {
return {
browser: "谷歌浏览器",
version: "Chrome/" + matchBS[2] || "0"
};
} else {
return {
browser: "Opera",
version: "opr/" + matchBS2[2] || "0"
};
}
} //IE最新版
matchBS = rEdge.exec(ua);
if (matchBS != null && !window.attachEvent) {
return {
browser: "Microsoft Edge",
version: "Chrome/" + matchBS[2] || "0"
};
} //UC浏览器
matchBS = rUC.exec(ua);
if (matchBS != null && !window.attachEvent) {
return {
browser: "UC",
version: "Chrome/" + matchBS[2] || "0"
};
} //火狐浏览器
matchBS = rFirefox.exec(ua);
if (matchBS != null && !window.attachEvent) {
return {
browser: "火狐",
version: "Firefox/" + matchBS[2] || "0"
};
} //Oper浏览器
matchBS = rOpera.exec(ua);
if (matchBS != null && !window.attachEvent) {
return {
browser: "Opera",
version: "Chrome/" + matchBS[2] || "0"
};
} //遨游
matchBS = rMaxthon.exec(ua);
if (matchBS != null && !window.attachEvent) {
return {
browser: "遨游",
version: "Chrome/" + matchBS[2] || "0"
};
} //2345浏览器
matchBS = r2345.exec(ua);
if (matchBS != null && !window.attachEvent) {
return {
browser: "2345",
version: "Chrome/ " + matchBS[2] || "0"
};
} //QQ浏览器
matchBS = rQQ.exec(ua);
if (matchBS != null && !window.attachEvent) {
return {
browser: "QQ",
version: "Chrome/" + matchBS[2] || "0"
};
} //Safari(苹果)浏览器
matchBS = rSafari.exec(ua);
if (matchBS != null && !window.attachEvent && !window.chrome && !window.opera) {
return {
browser: "Safari",
version: "Safari/" + matchBS[1] || "0"
};
}
},
// 获取异常组件名称
getComponentName: function getComponentName(vm) {
if (vm.$root === vm) return 'root';
var name = vm._isVue ? vm.$options && vm.$options.name || vm.$options && vm.$options._componentTag : vm.name;
return (name ? "component <".concat(name, ">") : 'anonymous component') + (vm._isVue && vm.$options && vm.$options.__file ? " at ".concat(vm.$options && vm.$options.__file) : '');
}
};
/* eslint-disable quotes */
/* eslint-disable space-before-function-paren */
var LsUtils = /*#__PURE__*/function () {
function LsUtils() {
_classCallCheck(this, LsUtils);
}
_createClass(LsUtils, [{
key: "set",
value: function set(key, val) {
if (_typeof(val) === "object") {
val = JSON.stringify(val);
}
localStorage.setItem(key, val);
}
}, {
key: "get",
value: function get(key) {
var defaultVal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
return localStorage.getItem(key) || defaultVal;
}
}, {
key: "getObj",
value: function getObj(key, defaultVal) {
var val = this.get(key, null);
if (val) {
return JSON.parse(val);
}
return defaultVal || null;
}
}, {
key: "remove",
value: function remove(key) {
localStorage.removeItem(key);
}
}]);
return LsUtils;
}();
var lsUtils = new LsUtils();
/* eslint-disable quotes */
/* eslint-disable space-before-function-paren */
var utils$2 = {
// 判断是否为对象
isObject: function isObject(obj) {
return Object.prototype.toString.call(obj) === "[object Object]";
},
// 判断是否为数组
isArray: function isArray(a) {
return Object.prototype.toString.call(a) == "[object Array]";
},
// 判断是否为字符串
isString: function isString(str) {
return typeof str === "string";
},
isEmpty: function isEmpty(obj) {
if (typeof obj === "undefined" || obj == null || obj == "") {
return true;
}
return false;
},
// 时间字符串比较 2019-12-12 13:13:13
CompareDate: function CompareDate(d1, d2) {
return new Date(d1.replace(/-/g, "/")) > new Date(d2.replace(/-/g, "/"));
}
};
/* eslint-disable quotes */
/* eslint-disable space-before-function-paren */
var handleDebounce = function handleDebounce(action, delay) {
var timer = null;
return function (ls, todayLs, today) {
// console.log("触发调用", todayLs);
var self = this;
if (timer) {
ls[today] = todayLs;
lsUtils.set("frontLogger", ls);
} // args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
// console.log("最后调用", todayLs);
action.call(self, ls, todayLs, today);
}, delay);
};
};
var reportHandller = {
// 查询当天是否有上报
init: function init(logger) {
// 查询上一日 byNum byDay onErrorOffline 残留未上传数据
var today = logger.today;
var ls = lsUtils.getObj("frontLogger", {}); // let copyLs = JSON.parse(JSON.stringify(ls));
for (var key in ls) {
// 判断key是否为日期格式 xxx-xx-xx
var arr = key.split("-");
if (arr.length == 3) {
var isYestoday = utils$2.CompareDate(today, key); // console.log(isYestoday);
if (isYestoday) {
// 上传以前数据
// console.log("上传以前数据");
var yestodayLs = ls[key];
if (yestodayLs.list.length > 0) {
var dataObj = {
list: yestodayLs.list
};
this.onErrorBatch && this.onErrorBatch(dataObj);
var reb = lsUtils.getObj("frontLogger", {});
var copyLs = JSON.parse(JSON.stringify(reb));
delete copyLs[key];
lsUtils.set("frontLogger", copyLs);
}
}
}
}
reportHandller.handleDebounceFn = handleDebounce(reportHandller.reportByList, 500);
},
report: function report(logger, params) {
var reportMode = logger.reportMode;
params = logger.formatErrorInfo(params);
if (params.fileName && params.fileName.indexOf("LdEmbed.min") != -1) {
console.warn("front_logger report warn");
return;
}
switch (reportMode) {
case "onError":
logger.reportError(params, false);
break;
case "byNum":
reportHandller.reportByNum(logger, params);
break;
case "byDay":
reportHandller.reportByDay(logger, params);
break;
case "onErrorOffline":
reportHandller.reportOnErrorOffline(logger, params);
break;
default:
console.warn("frontLogger > no this reportMode : ".concat(reportMode));
logger.reportError(params, false);
break;
}
},
reportOnErrorOffline: function reportOnErrorOffline(logger, params) {
var today = logger.today;
var limitNum = logger.limitNum;
var ls = lsUtils.getObj("frontLogger", {});
var initLs = reportHandller.getInitLs(today);
var todayLs = ls[today] || initLs[today];
if (params.online) {
logger.onError && logger.reportError(params);
} else if (todayLs && todayLs.list) {
todayLs.list.push(params);
ls[today] = todayLs;
lsUtils.set("frontLogger", ls);
}
},
reportByDay: function reportByDay(logger, params) {
var today = logger.today;
var limitNum = logger.limitNum;
var ls = lsUtils.getObj("frontLogger", {});
var initLs = reportHandller.getInitLs(today);
var todayLs = ls[today] || initLs[today];
if (todayLs.byNum && todayLs.byNum.list) {
todayLs.list.push(params); // 不能超过最大缓存值
if (todayLs.list.length > limitNum - 1) {
var dataObj = {
list: todayLs.list
};
console.log("excess limitNum reportByDay");
this.onErrorBatch && this.onErrorBatch(dataObj);
todayLs.list = [];
}
ls[today] = todayLs;
lsUtils.set("frontLogger", ls);
}
},
handleDebounceFn: null,
reportByNum: function reportByNum(logger, params) {
var today = logger.today;
var reportNum = logger.reportNum;
var ls = lsUtils.getObj("frontLogger", {}); // console.log(ls);
var initLs = reportHandller.getInitLs(today);
var todayLs = ls[today] || initLs[today];
if (todayLs && todayLs.list) {
todayLs.list.push(params);
if (todayLs.list.length > reportNum - 1) {
// if (true) {
// console.log("满10条 发送数据 清空缓存");
reportHandller.handleDebounceFn(ls, todayLs, today);
} else {
ls[today] = todayLs;
lsUtils.set("frontLogger", ls);
}
}
},
reportByList: function reportByList(ls, todayLs, today) {
var dataObj = {
list: todayLs.list
};
this.onErrorBatch && this.onErrorBatch(dataObj);
},
getInitLs: function getInitLs(today) {
var initLs = {};
initLs[today] = {
list: []
};
return initLs;
}
};
// 存储数据结构 frontLogger
// {
// "dayStr":{
// byNum:{
// list:[]
// },
// byDay:{
// list:[]
// },
// onErrorOffline:{
// list:[]
// }
// }
// }
// type异常类型 warn info caught 手动上报异常 unCaught 自动捕获代码异常 sourceError 资源加载异常 httpError 请求异常 unhandledRejection 未处理promise异常 handledRejection
var Logger = /*#__PURE__*/function () {
function Logger() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Logger);
this.apikey = options.apikey; // 是否禁用 logger 不收集任何信息
this.silent = options.silent || false; // 是否收集Promise异常
this.silentPromise = options.silentPromise || false; // 是否开启用户行为录制
this.silentVideo = options.silentVideo || false; // 异常上传模式 onError 立即上传 byNum 按天存储满多少个上传 byDay 按天上传 onErrorOffline 立即上报且支持线下缓存
this.reportMode = options.reportMode || 'onError'; // 满10条数据上报一次
this.reportNum = options.reportNum || 10; // 缓存数据最大数
this.limitNum = options.limitNum || 20; // 环境信息
this.env = options.env; // 用户信息
this.ip = options.ip;
this.cityNo = options.cityNo;
this.cityName = options.cityName;
this.today = "".concat(new Date().getFullYear(), "-").concat(new Date().getMonth() + 1, "-").concat(new Date().getDate());
this.onError = options.onError;
this.onErrorBatch = options.onErrorBatch;
this.onErrorByImg = options.onErrorByImg;
this.init();
} // 初始化 logger 框架内使用
_createClass(Logger, [{
key: "init",
value: function init() {
if (!this.apikey) console.warn('logger 缺少apikey');
if (this.envMoniter()) {
this.createCityInfo();
this.proxyWindowError();
}
} // 发送错误对象信息
}, {
key: "reportObjectByIMG",
value: function reportObjectByIMG(obj) {
var paramStr = '';
for (var key in obj) {
paramStr = "".concat(paramStr + key, "=").concat(obj[key], "&");
}
this.onErrorByImg(paramStr);
} // 上报http异常 用于手动
}, {
key: "reportHttpError",
value: function reportHttpError(errorInfo) {
var flag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
errorInfo.type = 'httpError';
this.reportError(errorInfo, flag);
}
}, {
key: "reportInfo",
value: function reportInfo(errorInfo) {
var flag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
errorInfo.type = 'info';
this.reportError(errorInfo, flag);
}
}, {
key: "reportWarning",
value: function reportWarning(errorInfo) {
var flag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
errorInfo.type = 'warn';
this.reportError(errorInfo, flag);
} // 上报promise异常捕获信息 用于手动
}, {
key: "reportHandledRejection",
value: function reportHandledRejection(errorInfo) {
var flag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
errorInfo.type = 'handledRejection';
this.reportError(errorInfo, flag);
} // 默认type caught 用于手动 flag是否需要获取基础信息baseInfo和MetaData
}, {
key: "reportError",
value: function reportError(errorInfo) {
var flag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
// 是否需要获取基础信息 立即发送
if (flag) {
var initParam = {
apikey: this.apikey,
ip: this.ip,
cityNo: this.cityNo,
cityName: this.cityName,
emitTime: new Date(),
type: errorInfo.type ? errorInfo.type : 'caught'
};
var baseInfo = utils.getBaseInfo();
var metaData = this.getMetaData(errorInfo.metaData);
errorInfo = Object.assign({}, initParam, baseInfo, errorInfo, metaData);
}
this.onError && this.onError(errorInfo);
} // 批量上传异常数据
}, {
key: "reportErrorList",
value: function reportErrorList(list) {
var flag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var dataObj = {
list: list
};
if (flag) {// 获取baseInfo等基础信息
}
this.onErrorBatch && this.onErrorBatch(dataObj);
}
}, {
key: "initVueErrorHandler",
value: function initVueErrorHandler(vue) {
var self = this;
vue.config.errorHandler = function (err, vm, info) {
// handle error
// `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子
// 只在 2.2.0+ 可用
console.error('捕获 Vue errror', err); // console.log(info);
var componentName = utils.getComponentName(vm);
var propsData = vm.$options && vm.$options.propsData;
var message = err.message,
name = err.name,
fileName = err.fileName,
lineNumber = err.lineNumber,
columnNumber = err.columnNumber,
stack = err.stack;
var initParam = {
apikey: self.apikey,
ip: self.ip,
cityNo: self.cityNo,
cityName: self.cityName
};
var stackStr = stack.toString();
var arr = stackStr.split(/[\n]/);
if (arr.length > 1 && !fileName) {
var str = arr[1];
var tempArr = str.split('(');
if (tempArr.length == 2) {
str = tempArr[1];
var tmpArr = str.split(':');
if (tmpArr.length > 1) {
lineNumber = tmpArr[tmpArr.length - 2];
columnNumber = tmpArr[tmpArr.length - 1];
fileName = str.replace(":".concat(lineNumber, ":").concat(columnNumber), '');
columnNumber = columnNumber.replace(')', ''); // console.log(lineNumber);
// console.log(columnNumber);
// console.log(fileName);
}
}
}
var errorInfo = {
name: name,
message: "".concat(name, ":").concat(message),
fileName: fileName,
lineNumber: lineNumber,
columnNumber: columnNumber,
componentName: componentName,
type: 'unCaught',
emitTime: new Date(),
propsData: propsData ? JSON.stringify(propsData) : '',
stack: stack.toString()
};
var baseInfo = utils.getBaseInfo();
var metaData = self.getMetaData();
var params = Object.assign({}, initParam, baseInfo, metaData, errorInfo); // console.log(params);
reportHandller.report(self, params);
};
} // 格式化上报数据
}, {
key: "formatErrorInfo",
value: function formatErrorInfo(errorInfo) {
// 内容截取
if (errorInfo.message && errorInfo.message.length > 2040) {
errorInfo.message = errorInfo.message.substring(0, 2040);
}
if (errorInfo.stack && errorInfo.stack.length > 60000) {
errorInfo.stack = errorInfo.stack.substring(0, 60000);
}
if (errorInfo.name && errorInfo.name.length > 254) {
errorInfo.name = errorInfo.name.substring(0, 254);
}
return errorInfo;
}
}, {
key: "getMetaData",
value: function getMetaData(defaultInfo) {
defaultInfo = defaultInfo || {};
var metaData = defaultInfo; // 其它途径获取的metaData ...
return {
metaData: JSON.stringify(metaData)
};
} // 环境检测
}, {
key: "envMoniter",
value: function envMoniter() {
if (this.silent === true) {
console.log('silent true');
return false;
}
return true;
} // 获取客户端ip和城市信息
}, {
key: "createCityInfo",
value: function createCityInfo() {
var _this = this;
if (!this.cityName || !this.cityNo) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://pv.sohu.com/cityjson?ie=utf-8";
document.body.appendChild(script);
script.onload = function () {
if (window.returnCitySN) {
_this.ip = returnCitySN.cip;
_this.cityNo = returnCitySN.cid;
_this.cityName = returnCitySN.cname;
}
};
}
}
}, {
key: "proxyWindowError",
value: function proxyWindowError() {
var _this2 = this;
var initParam = {
apikey: this.apikey,
ip: this.ip,
cityNo: this.cityNo,
cityName: this.cityName
}; // 初始化 reportHandller
reportHandller.init(this);
window.addEventListener('error', function (event) {
// 过滤js error
var target = event.target || event.srcElement;
var isElementTarget = target instanceof HTMLScriptElement || target instanceof HTMLLinkElement || target instanceof HTMLImageElement;
if (!isElementTarget) {
// js报错
var fileName, lineNumber, columnNumber;
fileName = event.filename;
lineNumber = event.lineno;
columnNumber = event.colno;
var title = event.message;
var stack = event.error ? event.error.stack : '';
var errorInfo = {
name: event.message,
message: event.message,
fileName: fileName,
lineNumber: lineNumber,
columnNumber: columnNumber,
type: 'unCaught',
emitTime: new Date(),
stack: stack.toString()
};
var baseInfo = utils.getBaseInfo();
var metaData = _this2.getMetaData();
var params = Object.assign({}, initParam, baseInfo, metaData, errorInfo); // console.log(params);
reportHandller.report(_this2, params);
} else {
// 上报资源地址
var src = target.src || target.href; // console.log("资源加载异常", event);
var tagName = target.tagName;
var outerHTML = target.outerHTML;
var selector = '';
var paths = event.path;
if (tagName === "IMG" && outerHTML.indexOf('src=""') > -1) {
return;
}
if (paths && paths.length > 0) {
paths.reverse(); // console.log(paths);
var arr = [];
if (paths.length > 4) {
arr = paths.slice(paths.length - 5);
} else {
arr = paths;
}
arr.forEach(function (item, index) {
var className = item.className ? ".".concat(item.className.replace(/\s+/g, '.')) : '';
var tagName = item.tagName || item.nodeName || 'window';
if (index == arr.length - 1) {
selector = selector + tagName.toLowerCase() + className;
} else {
selector = "".concat(selector + tagName.toLowerCase() + className, " > ");
}
});
} else {
// 通过parentNode来寻找 先不递归 按层获取
var selectorArr = [];
var currentNode = target;
var _tagName = currentNode.tagName.toLowerCase();
var className = currentNode.className ? ".".concat(currentNode.className.replace(/\s+/g, '.')) : '';
if (_tagName != 'body') {
selectorArr.push(_tagName + className);
currentNode = currentNode.parentNode;
_tagName = currentNode.tagName.toLowerCase();
className = currentNode.className ? ".".concat(currentNode.className.replace(/\s+/g, '.')) : '';
if (_tagName != 'body') {
selectorArr.push(_tagName + className);
currentNode = currentNode.parentNode;
_tagName = currentNode.tagName.toLowerCase();
className = currentNode.className ? ".".concat(currentNode.className.replace(/\s+/g, '.')) : '';
if (_tagName != 'body') {
selectorArr.push(_tagName + className);
currentNode = currentNode.parentNode;
_tagName = currentNode.tagName.toLowerCase();
className = currentNode.className ? ".".concat(currentNode.className.replace(/\s+/g, '.')) : '';
selectorArr.push(_tagName + className);
}
}
}
selectorArr.reverse();
selectorArr.forEach(function (item, index) {
if (index == selectorArr.length - 1) {
selector += item;
} else {
selector = "".concat(selector + item, " > ");
}
});
} // outerHTML XPath status 404 statusText selector
var _errorInfo = {
name: 'sourceError',
message: '资源加载异常',
src: src,
tagName: tagName,
outerHTML: outerHTML,
status: 404,
statusText: 'Not Found',
selector: selector,
emitTime: new Date(),
type: 'sourceError'
};
var _baseInfo = utils.getBaseInfo();
var _metaData = _this2.getMetaData();
var _params = Object.assign({}, initParam, _baseInfo, _metaData, _errorInfo); // console.log(params);
reportHandller.report(_this2, _params);
}
}, true); // 被Vue捕获的错误
if (window.Vue) {
this.initVueErrorHandler(window.Vue);
}
if (this.silentPromise) {
// 未处理的promise错误 rejectionhandled unhandledrejection
window.addEventListener('unhandledrejection', function (event) {
// 错误的详细信息在reason字段
// demo:settimeout error
// console.log('未处理的promise错误', event);
var message = event.reason.message;
var stack = event.reason.stack;
var type = 'unhandledRejection';
if (!message && !stack) {
message = 'caught promise error';
stack = JSON.stringify(event.reason);
}
var errorInfo = {
name: event.reason.stack ? event.reason.stack.name : message,
message: message,
stack: stack,
type: type,
columnNumber: event.reason.columnNumber,
fileName: event.reason.fileName,
lineNumber: event.reason.lineNumber,
emitTime: new Date()
};
var reason = event.reason;
var metaData = {}; // 未处理网络promiase异常
if (message == 'Network Error' || message == '网关超时') {
type = 'httpError';
errorInfo.type = 'httpError';
if (reason.config) {
var requestInfo = {
method: reason.config.method,
url: reason.config.url,
headers: reason.config.headers
};
errorInfo.src = reason.config.url;
metaData = Object.assign(metaData, requestInfo);
var responseInfo = {}; // 未验证 待验证
if (reason.response) {
errorInfo.status = reason.response.status;
errorInfo.statusText = reason.response.statusText;
}
}
} // 未处理promise里面的语法异常
if (message != 'Network Error' && message != 'caught promise error' && message != '网关超时') {
var stackStr = event.reason.stack.toString();
var arr = stackStr.split(/[\n]/);
var fileName, lineNumber, columnNumber;
if (arr.length > 1 && arr[1].indexOf('at') != -1 && !errorInfo.fileName) {
var str = arr[1];
var tempArr = str.split('(');
if (tempArr.length == 2) {
str = tempArr[1];
var tmpArr = str.split(':');
if (tmpArr.length > 1) {
lineNumber = tmpArr[tmpArr.length - 2];
columnNumber = tmpArr[tmpArr.length - 1];
fileName = str.replace(":".concat(lineNumber, ":").concat(columnNumber), '');
columnNumber = columnNumber.replace(')', ''); // console.log(lineNumber);
// console.log(columnNumber);
// console.log(fileName);
errorInfo.lineNumber = lineNumber;
errorInfo.columnNumber = columnNumber;
errorInfo.fileName = fileName;
}
}
}
} // console.log(errorInfo);
var baseInfo = utils.getBaseInfo();
metaData = _this2.getMetaData(metaData);
var params = Object.assign({}, initParam, baseInfo, metaData, errorInfo); // console.log(params);
reportHandller.report(_this2, params);
}); // 处理的promise错误
window.addEventListener('rejectionhandled', function (event) {
// 错误的详细信息在reason字段
// demo:settimeout error
// console.log('rejectionhandled promise error', event);
var title = event.reason.message;
var stack = event.reason.stack;
});
}
} // 用户操作跟踪
}, {
key: "evtMoniter",
value: function evtMoniter() {// ... TODO
}
}]);
return Logger;
}();
return Logger;
})));