UNPKG

ld-embed

Version:
1,254 lines (1,053 loc) 38.8 kB
/*! * 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; })));