mon-reactive-h5 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,12 +3,6 @@
3
3
  function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
4
4
  function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
5
5
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
6
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
7
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
9
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
10
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
11
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
12
6
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
13
7
  function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
14
8
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -47,26 +41,15 @@ Object.defineProperty(exports, "__esModule", {
47
41
  exports.MonitorSDK = void 0;
48
42
  var BatchReporter_1 = require("./BatchReporter");
49
43
  var reporters_1 = require("./reporters");
50
- /**
51
- * 前端监控SDK核心类
52
- */
53
44
  var MonitorSDK = /*#__PURE__*/function () {
54
- /**
55
- * 构造函数
56
- * @param config SDK配置
57
- */
58
45
  function MonitorSDK(config) {
59
46
  _classCallCheck(this, MonitorSDK);
60
- // 记录上一页URL,用于单页应用路由变化时的referrer
61
47
  this.lastPageUrl = document.referrer || '';
62
48
  this.appId = config.appId || '';
63
49
  this.reportUrl = config.reportUrl || '';
64
- // 确保sampleRates是Record<string, number>类型
65
50
  if (config.sampleRates) {
66
- this.sampleRates = Object.entries(config.sampleRates).reduce(function (acc, _ref) {
67
- var _ref2 = _slicedToArray(_ref, 2),
68
- key = _ref2[0],
69
- value = _ref2[1];
51
+ this.sampleRates = Object.keys(config.sampleRates).reduce(function (acc, key) {
52
+ var value = config.sampleRates[key];
70
53
  acc[key] = value !== undefined ? value : 1;
71
54
  return acc;
72
55
  }, {});
@@ -84,65 +67,41 @@ var MonitorSDK = /*#__PURE__*/function () {
84
67
  interval: config.interval || 5000
85
68
  });
86
69
  this.sessionId = this.generateSessionId();
87
- // 优先使用配置中的userId,如果没有则尝试从token中提取
88
70
  this.userId = config.userId || this.getUserIdFromToken();
89
- // 获取版本号,PC端从process.env.VUE_APP_VERSION获取,小程序和APP使用各自的版本号
90
71
  this.version = this.getAppVersion(config);
91
72
  this.init();
92
73
  }
93
- /**
94
- * 获取应用版本号
95
- */
96
74
  return _createClass(MonitorSDK, [{
97
75
  key: "getAppVersion",
98
76
  value: function getAppVersion(config) {
99
- // 优先使用配置传入的版本号
100
77
  if (config.version) {
101
78
  return config.version;
102
79
  }
103
- // PC端尝试从环境变量获取
104
80
  if (typeof process !== 'undefined' && process.env && process.env.VUE_APP_VERSION) {
105
81
  return process.env.VUE_APP_VERSION;
106
82
  }
107
- // 小程序环境检测
108
83
  if (typeof wx !== 'undefined' && wx.getSystemInfoSync) {
109
84
  try {
110
85
  var systemInfo = wx.getSystemInfoSync();
111
86
  return systemInfo.AppVersion || systemInfo.version || '1.0.0';
112
- } catch (e) {
113
- // 忽略错误
114
- }
87
+ } catch (e) {}
115
88
  }
116
- // APP环境检测
117
89
  if (typeof window !== 'undefined' && window.navigator && window.navigator.userAgent) {
118
- // 根据实际APP的userAgent格式调整
119
90
  var ua = window.navigator.userAgent;
120
- // 这里可以根据具体APP的UA格式进行解析
121
91
  }
122
- return '1.0.0'; // 默认版本号
92
+ return '1.0.0';
123
93
  }
124
- /**
125
- * 生成会话ID
126
- */
127
94
  }, {
128
95
  key: "generateSessionId",
129
96
  value: function generateSessionId() {
130
97
  return "".concat(Date.now(), "_").concat(Math.random().toString(36).substring(2, 9));
131
98
  }
132
- /**
133
- * 从token中提取userId
134
- * 小程序环境:直接从本地缓存中取"token"
135
- * 网页环境:先尝试从sessionStorage中取"-token",再尝试从cookie里取"Admin-Token"
136
- * 取出token后截取最后12位作为userid
137
- */
138
99
  }, {
139
100
  key: "getUserIdFromToken",
140
101
  value: function getUserIdFromToken() {
141
102
  var token = null;
142
- // 1. 先检查是否为小程序环境
143
103
  try {
144
104
  if (typeof wx !== 'undefined' && wx.getStorageSync) {
145
- // 小程序环境,直接从本地缓存中获取token
146
105
  var wxToken = wx.getStorageSync('token');
147
106
  if (wxToken) {
148
107
  token = wxToken;
@@ -151,7 +110,6 @@ var MonitorSDK = /*#__PURE__*/function () {
151
110
  } catch (error) {
152
111
  console.warn('Failed to get token from wx storage:', error);
153
112
  }
154
- // 2. 如果不是小程序环境或未获取到token,尝试从sessionStorage中获取token
155
113
  if (!token) {
156
114
  try {
157
115
  if (typeof window !== 'undefined' && window.sessionStorage) {
@@ -161,7 +119,6 @@ var MonitorSDK = /*#__PURE__*/function () {
161
119
  console.warn('Failed to get token from sessionStorage:', error);
162
120
  }
163
121
  }
164
- // 3. 如果sessionStorage中没有token,尝试从cookie中获取
165
122
  if (!token) {
166
123
  try {
167
124
  if (typeof document !== 'undefined') {
@@ -174,63 +131,33 @@ var MonitorSDK = /*#__PURE__*/function () {
174
131
  console.warn('Failed to get token from cookie:', error);
175
132
  }
176
133
  }
177
- // 4. 从token中提取userId(截取最后12位)
178
134
  if (token && token.length >= 12) {
179
135
  return token.slice(-12);
180
136
  }
181
137
  return undefined;
182
138
  }
183
- /**
184
- * 初始化SDK
185
- */
186
139
  }, {
187
140
  key: "init",
188
141
  value: function init() {
189
142
  var _this = this;
190
- // 初始化各类监控
191
143
  this.initPageViewMonitor();
192
144
  this.initErrorMonitor();
193
145
  this.initApiMonitor();
194
146
  this.initResourceMonitor();
195
- // 页面卸载时清理
196
147
  window.addEventListener('unload', function () {
197
148
  _this.cleanup();
198
149
  });
199
150
  }
200
- /**
201
- * 清理资源
202
- */
203
151
  }, {
204
152
  key: "cleanup",
205
153
  value: function cleanup() {
206
- // 恢复原始方法
207
- if (this.originalFetch) {
208
- window.fetch = this.originalFetch;
209
- }
210
154
  if (this.originalXHRSend) {
211
155
  XMLHttpRequest.prototype.send = this.originalXHRSend;
212
156
  }
213
- // 销毁批量上报器
214
157
  if (this.batchReporter) {
215
158
  this.batchReporter.destroy();
216
159
  }
217
160
  }
218
- /**
219
- * 恢复原始方法
220
- */
221
- }, {
222
- key: "restoreOriginalMethods",
223
- value: function restoreOriginalMethods() {
224
- if (this.originalFetch) {
225
- window.fetch = this.originalFetch;
226
- }
227
- if (this.originalXHRSend) {
228
- XMLHttpRequest.prototype.send = this.originalXHRSend;
229
- }
230
- }
231
- /**
232
- * 页面浏览监控
233
- */
234
161
  }, {
235
162
  key: "initPageViewMonitor",
236
163
  value: function initPageViewMonitor() {
@@ -242,9 +169,7 @@ var MonitorSDK = /*#__PURE__*/function () {
242
169
  referrer: document.referrer,
243
170
  timestamp: startTime
244
171
  };
245
- // 更新lastPageUrl为当前页面URL
246
172
  this.lastPageUrl = window.location.href;
247
- // 页面加载完成上报
248
173
  window.addEventListener('load', function () {
249
174
  var performanceData = _this2.getPerformanceData();
250
175
  _this2.reportPageView(Object.assign(Object.assign({}, pageInfo), {
@@ -253,26 +178,21 @@ var MonitorSDK = /*#__PURE__*/function () {
253
178
  performance: performanceData
254
179
  }));
255
180
  });
256
- // 单页应用路由变化监控
257
181
  if (window.history.pushState) {
258
182
  var originalPushState = window.history.pushState;
259
183
  var originalReplaceState = window.history.replaceState;
260
184
  var handleHistoryChange = function handleHistoryChange() {
261
- // 获取当前URL
262
185
  var currentUrl = window.location.href;
263
- // 只有当URL真正变化时才上报,避免replaceState导致的重复上报
264
186
  if (currentUrl !== _this2.lastPageUrl) {
265
187
  _this2.reportPageView({
266
188
  pageUrl: currentUrl,
267
189
  pageTitle: document.title,
268
190
  referrer: _this2.lastPageUrl,
269
- // 使用上一页URL作为referrer
270
191
  timestamp: Date.now(),
271
192
  duration: 0,
272
193
  isFirstVisit: false,
273
194
  performance: _this2.getPerformanceData()
274
195
  });
275
- // 更新上一页URL为当前URL
276
196
  _this2.lastPageUrl = currentUrl;
277
197
  }
278
198
  };
@@ -284,7 +204,6 @@ var MonitorSDK = /*#__PURE__*/function () {
284
204
  handleHistoryChange();
285
205
  };
286
206
  window.history.replaceState = function () {
287
- // 保存调用前的URL
288
207
  var prevUrl = window.location.href;
289
208
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
290
209
  args[_key2] = arguments[_key2];
@@ -292,18 +211,13 @@ var MonitorSDK = /*#__PURE__*/function () {
292
211
  originalReplaceState.apply(this, args);
293
212
  handleHistoryChange();
294
213
  };
295
- // 监听popstate事件
296
214
  window.addEventListener('popstate', handleHistoryChange);
297
215
  }
298
216
  }
299
- /**
300
- * 错误监控
301
- */
302
217
  }, {
303
218
  key: "initErrorMonitor",
304
219
  value: function initErrorMonitor() {
305
220
  var _this3 = this;
306
- // JS错误
307
221
  window.addEventListener('error', function (event) {
308
222
  _this3.reportJSError({
309
223
  message: event.message,
@@ -316,7 +230,6 @@ var MonitorSDK = /*#__PURE__*/function () {
316
230
  timestamp: Date.now()
317
231
  });
318
232
  });
319
- // Promise错误
320
233
  window.addEventListener('unhandledrejection', function (event) {
321
234
  _this3.reportJSError({
322
235
  message: event.reason ? String(event.reason) : 'Promise rejection',
@@ -330,118 +243,45 @@ var MonitorSDK = /*#__PURE__*/function () {
330
243
  });
331
244
  });
332
245
  }
333
- /**
334
- * API监控
335
- */
336
246
  }, {
337
247
  key: "initApiMonitor",
338
248
  value: function initApiMonitor() {
339
- // 生成请求ID
340
249
  var generateRequestId = function generateRequestId() {
341
250
  return "".concat(Date.now(), "_").concat(Math.random().toString(36).substring(2, 11));
342
251
  };
343
- // 解析URL,分离基础URL和完整URL
344
252
  var parseUrl = function parseUrl(urlStr) {
345
253
  try {
346
254
  var urlList = urlStr.split('?');
347
- // 基础URL(不包含查询参数和hash)
348
255
  var baseUrl = urlList[0];
349
- // 完整URL(包含查询参数和hash)
350
256
  var fullUrl = urlStr;
351
257
  return {
352
258
  baseUrl: baseUrl,
353
259
  fullUrl: fullUrl
354
260
  };
355
261
  } catch (_a) {
356
- // 如果URL解析失败,则使用原始URL
357
262
  return {
358
263
  baseUrl: urlStr,
359
264
  fullUrl: urlStr
360
265
  };
361
266
  }
362
267
  };
363
- // 重写fetch
364
- // this.originalFetch = window.fetch;
365
- // window.fetch = async (...args) => {
366
- // const [url, options] = args;
367
- // const urlStr = typeof url === 'string' ? url : url.toString();
368
- // // 排除SDK自身的上报请求,避免死循环
369
- // // 1. 检查是否有特殊标记表示这是SDK内部请求
370
- // const isSdkInternalRequest = options?.headers?.['x-sdk-internal'] === 'true';
371
- // // 2. 检查是否是已知的SDK上报路径,包括批量上报相关路径
372
- // const knownReportPaths = ['/v1/report/collect', '/v1/report/collectImg', '/api/report/collect'];
373
- // const isKnownReportPath = knownReportPaths.some(path => urlStr.includes(path));
374
- // // 3. 检查是否是配置的上报URL
375
- // const isConfiguredReportUrl = this.reportUrl && urlStr.includes(this.reportUrl);
376
- // // 4. 对于没有头信息的请求(如sendBeacon和img上报),增加更严格的路径匹配
377
- // const isBatchReportPath = urlStr.includes('/v1/report/collect') || urlStr.includes('/v1/report/collectImg');
378
- // // 如果是SDK自身的上报请求,则直接使用原始fetch
379
- // if (isSdkInternalRequest || isKnownReportPath || isConfiguredReportUrl || isBatchReportPath) {
380
- // return this.originalFetch!(...args);
381
- // }
382
- // const startTime = Date.now();
383
- // const method = options?.method || 'GET';
384
- // const requestId = generateRequestId();
385
- // const { baseUrl, fullUrl } = parseUrl(urlStr);
386
- // try {
387
- // const response = await this.originalFetch!(...args);
388
- // const reportData = {
389
- // requestId,
390
- // url: baseUrl,
391
- // fullUrl,
392
- // method,
393
- // status: response.status,
394
- // isError: response.status >= 400,
395
- // responseTime: Date.now() - startTime,
396
- // timestamp: startTime,
397
- // pageUrl: window.location.href
398
- // };
399
- // // 上报API数据
400
- // this.reportApi(reportData);
401
- // return response;
402
- // } catch (error) {
403
- // const reportData = {
404
- // requestId,
405
- // url: baseUrl,
406
- // fullUrl,
407
- // method,
408
- // status: 0,
409
- // isError: true,
410
- // errorType: (error as Error).name || 'FetchError',
411
- // responseTime: Date.now() - startTime,
412
- // timestamp: startTime,
413
- // pageUrl: window.location.href
414
- // };
415
- // // 上报错误API
416
- // this.reportApi(reportData);
417
- // throw error;
418
- // }
419
- // };
420
- // 重写XMLHttpRequest
421
268
  var originalXHROpen = XMLHttpRequest.prototype.open;
422
269
  var originalSend = XMLHttpRequest.prototype.send;
423
270
  this.originalXHRSend = originalSend;
424
271
  var xhrMap = new WeakMap();
425
272
  var that = this;
426
- // 覆盖XMLHttpRequest.open方法
427
273
  var originalOpen = originalXHROpen;
428
274
  XMLHttpRequest.prototype.open = function (method, url, async, username, password) {
429
275
  var urlStr = typeof url === 'string' ? url : url.toString();
430
- // 排除SDK自身的上报请求,避免死循环
431
- // 1. 检查是否有特殊标记表示这是SDK内部请求(通过自定义属性)
432
276
  if (this._isSdkInternalRequest) {
433
277
  return originalOpen.call(this, method, url, async === undefined ? true : async, username, password);
434
278
  }
435
- // 2. 检查是否是已知的SDK上报路径,包括批量上报相关路径
436
279
  var knownReportPaths = ['/v1/report/collect', '/v1/report/collectImg', '/api/report/collect'];
437
280
  var isKnownReportPath = knownReportPaths.some(function (path) {
438
281
  return urlStr.includes(path);
439
282
  });
440
- // 3. 检查是否是配置的上报URL
441
283
  var isConfiguredReportUrl = that.reportUrl && urlStr.includes(that.reportUrl);
442
- // 4. 对于没有头信息的请求(如sendBeacon和img上报),增加更严格的路径匹配
443
284
  var isBatchReportPath = urlStr.includes('/v1/report/collect') || urlStr.includes('/v1/report/collectImg');
444
- // 如果是SDK自身的上报请求,则直接使用原始open方法
445
285
  if (isKnownReportPath || isConfiguredReportUrl || isBatchReportPath) {
446
286
  return originalOpen.call(this, method, url, async === undefined ? true : async, username, password);
447
287
  }
@@ -465,13 +305,59 @@ var MonitorSDK = /*#__PURE__*/function () {
465
305
  args[_key3] = arguments[_key3];
466
306
  }
467
307
  if (!xhrInfo) {
468
- // @ts-ignore
469
308
  return originalSend.apply(this, args);
470
309
  }
310
+ var requestBodySize = 0;
311
+ if (args && args[0] !== undefined && args[0] !== null) {
312
+ if (typeof args[0] === 'string') {
313
+ try {
314
+ requestBodySize = new TextEncoder().encode(args[0]).length;
315
+ } catch (e) {
316
+ requestBodySize = args[0].length;
317
+ }
318
+ } else if (args[0] instanceof FormData) {
319
+ requestBodySize = -1;
320
+ } else if (args[0] instanceof Blob) {
321
+ requestBodySize = args[0].size;
322
+ } else {
323
+ try {
324
+ var str = JSON.stringify(args[0]);
325
+ requestBodySize = new TextEncoder().encode(str).length;
326
+ } catch (e) {
327
+ requestBodySize = -1;
328
+ }
329
+ }
330
+ }
331
+ Object.assign(xhrInfo, {
332
+ requestBodySize: requestBodySize
333
+ });
471
334
  this.addEventListener('loadend', function () {
472
335
  var endTime = Date.now();
473
336
  var responseTime = endTime - xhrInfo.startTime;
474
337
  var status = _this4.status;
338
+ var responseBodySize = 0;
339
+ try {
340
+ if (_this4.responseText) {
341
+ responseBodySize = new TextEncoder().encode(_this4.responseText).length;
342
+ } else if (_this4.response) {
343
+ if (typeof _this4.response === 'string') {
344
+ responseBodySize = new TextEncoder().encode(_this4.response).length;
345
+ } else if (_this4.response instanceof ArrayBuffer) {
346
+ responseBodySize = _this4.response.byteLength;
347
+ } else if (_this4.response instanceof Blob) {
348
+ responseBodySize = _this4.response.size;
349
+ } else {
350
+ try {
351
+ var _str = JSON.stringify(_this4.response);
352
+ responseBodySize = new TextEncoder().encode(_str).length;
353
+ } catch (e) {
354
+ responseBodySize = -1;
355
+ }
356
+ }
357
+ }
358
+ } catch (e) {
359
+ responseBodySize = -1;
360
+ }
475
361
  var reportData = {
476
362
  requestId: xhrInfo.requestId,
477
363
  url: xhrInfo.url,
@@ -482,34 +368,31 @@ var MonitorSDK = /*#__PURE__*/function () {
482
368
  responseTime: responseTime,
483
369
  timestamp: xhrInfo.startTime,
484
370
  pageUrl: window.location.href,
485
- errorType: status === 0 ? 'NetworkError' : undefined
371
+ errorType: status === 0 ? 'NetworkError' : "HTTP".concat(status),
372
+ requestBodySize: requestBodySize,
373
+ responseBodySize: responseBodySize
486
374
  };
487
- // 上报API数据
488
375
  that.reportApi(reportData);
489
376
  });
490
377
  return originalSend.apply(this, args);
491
378
  };
492
379
  }
493
- /**
494
- * 资源监控
495
- */
496
380
  }, {
497
381
  key: "initResourceMonitor",
498
382
  value: function initResourceMonitor() {
499
383
  var _this5 = this;
500
- // 通过PerformanceObserver监控资源加载
501
384
  if ('PerformanceObserver' in window) {
502
385
  try {
503
386
  var observer = new PerformanceObserver(function (list) {
504
387
  list.getEntries().forEach(function (entry) {
505
388
  if (entry.entryType === 'resource') {
506
389
  var resourceEntry = entry;
507
- // 检查资源是否加载失败
508
- if (resourceEntry.responseStatus >= 400) {
390
+ var typedEntry = resourceEntry;
391
+ if (typedEntry.responseStatus && typedEntry.responseStatus >= 400) {
509
392
  _this5.reportResource({
510
393
  url: resourceEntry.name,
511
394
  type: _this5.getResourceType(resourceEntry.name),
512
- status: resourceEntry.responseStatus,
395
+ status: typedEntry.responseStatus,
513
396
  timestamp: resourceEntry.startTime,
514
397
  pageUrl: window.location.href,
515
398
  duration: resourceEntry.duration,
@@ -528,7 +411,6 @@ var MonitorSDK = /*#__PURE__*/function () {
528
411
  console.error('PerformanceObserver初始化失败:', error);
529
412
  }
530
413
  }
531
- // 监听资源错误事件
532
414
  window.addEventListener('error', function (event) {
533
415
  if (event.target && (event.target instanceof HTMLScriptElement || event.target instanceof HTMLLinkElement || event.target instanceof HTMLImageElement || event.target instanceof HTMLAudioElement || event.target instanceof HTMLVideoElement)) {
534
416
  var target = event.target;
@@ -546,26 +428,20 @@ var MonitorSDK = /*#__PURE__*/function () {
546
428
  }
547
429
  }, true);
548
430
  }
549
- /**
550
- * 获取资源类型
551
- */
552
431
  }, {
553
432
  key: "getResourceType",
554
433
  value: function getResourceType(url) {
555
434
  var _a;
556
435
  var ext = (_a = url.split('?')[0].split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
557
436
  if (!ext) return 'other';
558
- if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp', 'ico'].includes(ext)) return 'image';
559
- if (['js'].includes(ext)) return 'js';
560
- if (['css'].includes(ext)) return 'css';
561
- if (['woff', 'woff2', 'ttf', 'eot', 'otf'].includes(ext)) return 'font';
562
- if (['mp4', 'webm', 'ogg'].includes(ext)) return 'video';
563
- if (['mp3', 'wav', 'ogg'].includes(ext)) return 'audio';
437
+ if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp', 'ico'].indexOf(ext) !== -1) return 'image';
438
+ if (['js'].indexOf(ext) !== -1) return 'js';
439
+ if (['css'].indexOf(ext) !== -1) return 'css';
440
+ if (['woff', 'woff2', 'ttf', 'eot', 'otf'].indexOf(ext) !== -1) return 'font';
441
+ if (['mp4', 'webm', 'ogg'].indexOf(ext) !== -1) return 'video';
442
+ if (['mp3', 'wav', 'ogg'].indexOf(ext) !== -1) return 'audio';
564
443
  return 'other';
565
444
  }
566
- /**
567
- * 获取性能数据
568
- */
569
445
  }, {
570
446
  key: "getPerformanceData",
571
447
  value: function getPerformanceData() {
@@ -576,9 +452,6 @@ var MonitorSDK = /*#__PURE__*/function () {
576
452
  loadEventEnd: timing.loadEventEnd
577
453
  };
578
454
  }
579
- /**
580
- * 判断是否首次访问
581
- */
582
455
  }, {
583
456
  key: "isFirstVisit",
584
457
  value: function isFirstVisit() {
@@ -589,9 +462,6 @@ var MonitorSDK = /*#__PURE__*/function () {
589
462
  }
590
463
  return false;
591
464
  }
592
- /**
593
- * 上报页面浏览
594
- */
595
465
  }, {
596
466
  key: "reportPageView",
597
467
  value: function reportPageView(data) {
@@ -608,9 +478,6 @@ var MonitorSDK = /*#__PURE__*/function () {
608
478
  };
609
479
  this.doReport(payload, 'pageview');
610
480
  }
611
- /**
612
- * 上报JS错误
613
- */
614
481
  }, {
615
482
  key: "reportJSError",
616
483
  value: function reportJSError(data) {
@@ -626,9 +493,6 @@ var MonitorSDK = /*#__PURE__*/function () {
626
493
  };
627
494
  this.doReport(payload, 'jserror');
628
495
  }
629
- /**
630
- * 上报API数据
631
- */
632
496
  }, {
633
497
  key: "reportApi",
634
498
  value: function reportApi(data) {
@@ -644,9 +508,6 @@ var MonitorSDK = /*#__PURE__*/function () {
644
508
  };
645
509
  this.doReport(payload, 'api');
646
510
  }
647
- /**
648
- * 上报资源错误
649
- */
650
511
  }, {
651
512
  key: "reportResource",
652
513
  value: function reportResource(data) {
@@ -661,41 +522,25 @@ var MonitorSDK = /*#__PURE__*/function () {
661
522
  };
662
523
  this.doReport(payload, 'resource');
663
524
  }
664
- /**
665
- * 统一上报处理
666
- */
667
525
  }, {
668
526
  key: "doReport",
669
527
  value: function doReport(payload, type) {
670
528
  var _a;
671
- // 采样处理
672
529
  var sampleRate = (_a = this.sampleRates[type]) !== null && _a !== void 0 ? _a : 1;
673
530
  if (Math.random() > sampleRate) return;
674
- // 数据脱敏
675
531
  var sanitizedPayload = Object.assign(Object.assign({}, payload), {
676
532
  data: this.sanitizeData(Object.assign(Object.assign({}, payload.data), {
677
533
  version: this.version
678
534
  }))
679
535
  });
680
- // 根据数据类型选择上报方式
681
536
  if (type === 'pageview' && typeof navigator.sendBeacon === 'function') {
682
- // 页面浏览使用sendBeacon
683
537
  (0, reporters_1.reportByBeacon)(sanitizedPayload, this.reportUrl);
684
538
  } else if (type === 'jserror' || type === 'resource') {
685
- // 错误数据立即上报
686
- // reportByApi(sanitizedPayload, this.reportUrl).catch(() => {
687
- // // 降级到img上报
688
- // reportByImg(sanitizedPayload, this.reportUrl);
689
- // });
690
539
  (0, reporters_1.reportWithFallback)(sanitizedPayload, this.reportUrl);
691
540
  } else {
692
- // 其他数据批量上报
693
541
  this.batchReporter.report(sanitizedPayload);
694
542
  }
695
543
  }
696
- /**
697
- * 获取设备信息
698
- */
699
544
  }, {
700
545
  key: "getDeviceInfo",
701
546
  value: function getDeviceInfo() {
@@ -711,13 +556,9 @@ var MonitorSDK = /*#__PURE__*/function () {
711
556
  language: navigator.language || ''
712
557
  };
713
558
  }
714
- /**
715
- * 获取网络信息
716
- */
717
559
  }, {
718
560
  key: "getNetworkInfo",
719
561
  value: function getNetworkInfo() {
720
- // 安全地获取网络信息
721
562
  var connection = navigator.connection || null;
722
563
  if (connection) {
723
564
  return {
@@ -730,9 +571,6 @@ var MonitorSDK = /*#__PURE__*/function () {
730
571
  effectiveType: 'unknown'
731
572
  };
732
573
  }
733
- /**
734
- * 获取浏览器信息
735
- */
736
574
  }, {
737
575
  key: "getBrowser",
738
576
  value: function getBrowser(ua) {
@@ -743,20 +581,13 @@ var MonitorSDK = /*#__PURE__*/function () {
743
581
  if (ua.includes('Trident') || ua.includes('MSIE')) return 'IE';
744
582
  return 'Unknown';
745
583
  }
746
- /**
747
- * 获取浏览器版本
748
- */
749
584
  }, {
750
585
  key: "getBrowserVersion",
751
586
  value: function getBrowserVersion(ua) {
752
- // 简化版本,实际项目中可能需要更复杂的正则匹配
753
587
  var versionRegex = /(Chrome|Safari|Firefox|Edge|MSIE)\/?\s*(\d+\.\d*)/i;
754
588
  var match = ua.match(versionRegex);
755
589
  return match ? match[2] : 'Unknown';
756
590
  }
757
- /**
758
- * 获取操作系统
759
- */
760
591
  }, {
761
592
  key: "getOS",
762
593
  value: function getOS(ua) {
@@ -767,13 +598,9 @@ var MonitorSDK = /*#__PURE__*/function () {
767
598
  if (ua.includes('Linux')) return 'Linux';
768
599
  return 'Unknown';
769
600
  }
770
- /**
771
- * 获取操作系统版本
772
- */
773
601
  }, {
774
602
  key: "getOSVersion",
775
603
  value: function getOSVersion(ua) {
776
- // 简化版本
777
604
  if (ua.includes('Windows')) {
778
605
  if (ua.includes('Windows NT 10.0')) return '10';
779
606
  if (ua.includes('Windows NT 6.3')) return '8.1';
@@ -783,9 +610,6 @@ var MonitorSDK = /*#__PURE__*/function () {
783
610
  }
784
611
  return 'Unknown';
785
612
  }
786
- /**
787
- * 获取设备类型
788
- */
789
613
  }, {
790
614
  key: "getDeviceType",
791
615
  value: function getDeviceType() {
@@ -795,35 +619,22 @@ var MonitorSDK = /*#__PURE__*/function () {
795
619
  }
796
620
  return 'desktop';
797
621
  }
798
- /**
799
- * 数据脱敏
800
- */
801
622
  }, {
802
623
  key: "sanitizeData",
803
624
  value: function sanitizeData(data) {
804
- // 深拷贝数据,避免修改原始数据
805
625
  var sanitized = JSON.parse(JSON.stringify(data));
806
- // 脱敏处理函数
807
626
  var _sanitize = function sanitize(obj) {
808
627
  if (!obj || _typeof(obj) !== 'object') return obj;
809
- // 遍历对象属性
810
628
  Object.keys(obj).forEach(function (key) {
811
- // 对常见敏感字段进行脱敏
812
629
  if (['password', 'token', 'auth', 'credential', 'key'].some(function (sensitive) {
813
630
  return key.toLowerCase().includes(sensitive);
814
631
  })) {
815
632
  obj[key] = '***';
816
- }
817
- // 邮箱脱敏
818
- else if (key.toLowerCase().includes('email') && typeof obj[key] === 'string') {
633
+ } else if (key.toLowerCase().includes('email') && typeof obj[key] === 'string') {
819
634
  obj[key] = obj[key].replace(/(.{2})(.*)(@.*)/, '$1***$3');
820
- }
821
- // 手机号脱敏
822
- else if (key.toLowerCase().includes('phone') && typeof obj[key] === 'string') {
635
+ } else if (key.toLowerCase().includes('phone') && typeof obj[key] === 'string') {
823
636
  obj[key] = obj[key].replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
824
- }
825
- // 递归处理嵌套对象
826
- else if (_typeof(obj[key]) === 'object') {
637
+ } else if (_typeof(obj[key]) === 'object') {
827
638
  _sanitize(obj[key]);
828
639
  }
829
640
  });
@@ -831,14 +642,10 @@ var MonitorSDK = /*#__PURE__*/function () {
831
642
  _sanitize(sanitized);
832
643
  return sanitized;
833
644
  }
834
- /**
835
- * 上报自定义事件
836
- */
837
645
  }, {
838
646
  key: "reportCustomEvent",
839
647
  value: function reportCustomEvent(eventType, eventData) {
840
648
  var _a;
841
- // 根据采样率决定是否上报
842
649
  var sampleRate = (_a = this.sampleRates['custom']) !== null && _a !== void 0 ? _a : 1;
843
650
  if (Math.random() > sampleRate) {
844
651
  return;
@@ -856,12 +663,8 @@ var MonitorSDK = /*#__PURE__*/function () {
856
663
  pageUrl: window.location.href
857
664
  }
858
665
  };
859
- // 使用批量上报
860
666
  this.batchReporter.report(reportData);
861
667
  }
862
- /**
863
- * 立即上报缓冲区数据
864
- */
865
668
  }, {
866
669
  key: "flush",
867
670
  value: function flush() {
@@ -881,9 +684,6 @@ var MonitorSDK = /*#__PURE__*/function () {
881
684
  }, _callee, this);
882
685
  }));
883
686
  }
884
- /**
885
- * 销毁SDK实例
886
- */
887
687
  }, {
888
688
  key: "destroy",
889
689
  value: function destroy() {