monitor-track 1.14.0 → 1.15.0

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.
package/index.js CHANGED
@@ -34,8 +34,8 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
34
34
  reportUrl: '',
35
35
  projectID: '',
36
36
  maxLength: 1000,
37
- spa: false,
38
- hash: false,
37
+ spa: true,
38
+ hash: true,
39
39
  enableBehavior: true,
40
40
  enableError: true,
41
41
  enableErrorScreenshot: false,
@@ -43,6 +43,7 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
43
43
  enableVisualTrack: false,
44
44
  enableLagTrack: true,
45
45
  enableRecord: false,
46
+ enableOnlinePersons: true,
46
47
  ignore: {
47
48
  urls: [],
48
49
  errors: [],
@@ -81,6 +82,22 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
81
82
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
82
83
  PERFORMANCE OF THIS SOFTWARE.
83
84
  ***************************************************************************** */
85
+ /* global Reflect, Promise, SuppressedError, Symbol */
86
+
87
+ var extendStatics = function(d, b) {
88
+ extendStatics = Object.setPrototypeOf ||
89
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
90
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
91
+ return extendStatics(d, b);
92
+ };
93
+
94
+ function __extends(d, b) {
95
+ if (typeof b !== "function" && b !== null)
96
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
97
+ extendStatics(d, b);
98
+ function __() { this.constructor = d; }
99
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
100
+ }
84
101
 
85
102
  var __assign = function() {
86
103
  __assign = Object.assign || function __assign(t) {
@@ -136,7 +153,7 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
136
153
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
137
154
  };
138
155
 
139
- var version = "1.14.0";
156
+ var version = "1.15.0";
140
157
 
141
158
  var eventsMatrix = [[]];
142
159
  function enableRecordFunc() {
@@ -896,6 +913,8 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
896
913
  detail: 'de',
897
914
  /** 上报时带上的请求参数 */
898
915
  requestData: 'rD',
916
+ /** 上报时带上的响应结果 */
917
+ responseBody: 'rB',
899
918
  /** 上报时带上的请求方法 */
900
919
  method: 'rM'
901
920
  },
@@ -1022,6 +1041,10 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
1022
1041
  // 上报
1023
1042
  function report(data) {
1024
1043
  return new Promise(function (res) {
1044
+ var _a;
1045
+ if ((((_a = Config.ignore) === null || _a === void 0 ? void 0 : _a.urls) || []).some(function (url) { return location.href.includes(url); })) {
1046
+ return;
1047
+ }
1025
1048
  //在帧的空闲时间上报
1026
1049
  var dataCopy = JSON.parse(JSON.stringify(data));
1027
1050
  if (typeof window.requestIdleCallback === 'function') {
@@ -1283,175 +1306,456 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
1283
1306
  dpr: window.devicePixelRatio
1284
1307
  });
1285
1308
  }
1286
- function ajaxEventTrigger(event) {
1287
- var ajaxEvent = new CustomEvent(event, {
1288
- detail: this
1309
+
1310
+ var reconnectAndSendTimeout, websocketHeartBeatInterval, ws, userId = '';
1311
+ var remoteDebugEnable = false;
1312
+ var targetPlatform = '';
1313
+ var targetUserId = '';
1314
+ var originConsole = __assign({}, console);
1315
+ var formatConsole = function () {
1316
+ if (remoteDebugEnable)
1317
+ return;
1318
+ remoteDebugEnable = true;
1319
+ window.console = __assign({}, originConsole);
1320
+ var arr = ['debug', 'log', 'info', 'warn', 'error'];
1321
+ arr.forEach(function (item) {
1322
+ //@ts-ignore
1323
+ window.console[item] = function () {
1324
+ var args = [];
1325
+ for (var _i = 0; _i < arguments.length; _i++) {
1326
+ args[_i] = arguments[_i];
1327
+ }
1328
+ //@ts-ignore
1329
+ originConsole[item].apply(originConsole, args);
1330
+ var data = {
1331
+ origin: 'console',
1332
+ level: item,
1333
+ userId: userId,
1334
+ time: new Date().toLocaleString(),
1335
+ page: location.href,
1336
+ content: '',
1337
+ targetPlatform: targetPlatform,
1338
+ targetUserId: targetUserId
1339
+ };
1340
+ try {
1341
+ var content = JSON.stringify(args);
1342
+ data.content = content;
1343
+ }
1344
+ catch (err) {
1345
+ data.content = 'console内容解析错误: ' + err.stack || err.message || err.toString();
1346
+ }
1347
+ var msg = {
1348
+ type: WEBSOCKET_TYPE.DEBUG_INFO_UPLOAD,
1349
+ userId: userId,
1350
+ platform: 'monitor-track-sdk',
1351
+ data: data
1352
+ };
1353
+ wsSendFunc(msg);
1354
+ };
1289
1355
  });
1290
- window.dispatchEvent(ajaxEvent);
1291
- }
1292
- var OldXHR = window.XMLHttpRequest;
1293
- function newXHR() {
1294
- var realXHR = new OldXHR();
1295
- realXHR.addEventListener('loadstart', function () {
1296
- ajaxEventTrigger.call(this, 'ajaxLoadStart');
1297
- }, false);
1298
- realXHR.addEventListener('loadend', function () {
1299
- ajaxEventTrigger.call(this, 'ajaxLoadEnd');
1300
- }, false);
1301
- // 此处的捕获的异常会连日志接口也一起捕获,如果日志上报接口异常了,就会导致死循环了。
1302
- realXHR.onerror = function (e) {
1303
- // eslint-disable-next-line no-console
1304
- console.warn('realXHR.onerror, e', e);
1305
- };
1306
- return realXHR;
1356
+ };
1357
+ var resetConsole = function () {
1358
+ window.console = originConsole;
1359
+ remoteDebugEnable = false;
1360
+ };
1361
+ var uploadRequest = function (requestInfo) {
1362
+ // console.log('monitor-track-sdk: uploadRequest remoteDebugEnable', remoteDebugEnable);
1363
+ if (remoteDebugEnable) {
1364
+ var data = {
1365
+ origin: 'request',
1366
+ userId: userId,
1367
+ time: new Date().toLocaleString(),
1368
+ page: location.href,
1369
+ content: requestInfo,
1370
+ targetPlatform: targetPlatform,
1371
+ targetUserId: targetUserId
1372
+ };
1373
+ var msg = {
1374
+ type: WEBSOCKET_TYPE.DEBUG_INFO_UPLOAD,
1375
+ userId: userId,
1376
+ platform: 'monitor-track-sdk',
1377
+ data: data
1378
+ };
1379
+ // console.log('monitor-track-sdk: request-upload sent');
1380
+ wsSendFunc(msg);
1381
+ }
1382
+ };
1383
+ function enableOnlinePersonsFunc() {
1384
+ initWebsocket();
1307
1385
  }
1308
- /**
1309
- * 页面接口请求监控
1310
- */
1311
- var tempUrlInfo = {};
1312
- var recordXMLHttpRequestLog = function (XMLHttpRequestTimeout) {
1313
- XMLHttpRequestTimeout = typeof XMLHttpRequestTimeout === 'number' ? XMLHttpRequestTimeout : 1000;
1314
- var timeRecordArray = [];
1315
- //@ts-ignore
1316
- window.__XMLHttpRequest__ = window.XMLHttpRequest;
1317
- //@ts-ignore
1318
- window.XMLHttpRequest = newXHR;
1319
- window.addEventListener('ajaxLoadStart', function (e) {
1320
- var tempObj = {
1321
- timeStamp: new Date().getTime(),
1322
- event: e
1386
+ var WEBSOCKET_TYPE = {
1387
+ TRY_CONNECT: 'try-connect',
1388
+ CHECK_CONNECT: 'check-connect',
1389
+ PING: 'ping',
1390
+ PONG: 'pong',
1391
+ REPLY_SERVER_HEART_BEAT: 'reply-server-heart-beat',
1392
+ SOCKET_HEART_BEAT: 'socket-heart-beat',
1393
+ RESPONSE_DATE: 'response-date',
1394
+ REMOTE_DEBUG_ENABLE: 'remote-debug-enable',
1395
+ DEBUG_INFO_UPLOAD: 'debug-info-upload',
1396
+ REPlY_MESSAGE: 'reply-message'
1397
+ };
1398
+ var mounted = false;
1399
+ var initWebsocket = function () {
1400
+ if (window.WebSocket) {
1401
+ userId = localStorage.getItem('username') || getUid();
1402
+ closeWebsocket('');
1403
+ websocketHeartBeatInterval = setInterval(reconnectAndSend, 30000);
1404
+ var isLocal = Config.reportUrl.includes('http://');
1405
+ ws = new WebSocket("ws".concat(isLocal ? '' : 's', "://").concat(Config.reportUrl.replace(isLocal ? 'http://' : 'https://', '').replace('/s/r', ''), "?type=monitor-dsk"));
1406
+ ws.onopen = function () { return openWS(); };
1407
+ ws.onmessage = function (data) { return incomingMessage(data); };
1408
+ ws.onerror = function () {
1409
+ ws.close(1000);
1410
+ if (websocketHeartBeatInterval)
1411
+ clearInterval(websocketHeartBeatInterval);
1412
+ websocketHeartBeatInterval = setInterval(reconnectAndSend, 10000);
1323
1413
  };
1324
- timeRecordArray.push(tempObj);
1325
- });
1326
- window.addEventListener('ajaxLoadEnd', function () {
1327
- var timeRecordArrayCopy = [].concat(timeRecordArray);
1328
- var _loop_1 = function (i) {
1329
- if (timeRecordArrayCopy[i].event.detail && timeRecordArrayCopy[i].event.detail.status > 0) {
1330
- var currentTime = new Date().getTime();
1331
- var _a = timeRecordArrayCopy[i].event.detail, responseURL_1 = _a.responseURL, status_1 = _a.status, statusText = _a.statusText, timeStamp = _a.timeStamp;
1332
- var previousTime = timeStamp || timeRecordArrayCopy[i].timeStamp;
1333
- var loadTime = currentTime - previousTime;
1334
- var request = {
1335
- requestType: 'xhr',
1336
- responseURL: responseURL_1,
1337
- status: status_1,
1338
- loadTime: loadTime,
1339
- statusText: statusText,
1340
- reason: '',
1341
- detail: '',
1342
- requestData: '',
1343
- method: ''
1344
- };
1345
- if (loadTime && loadTime > XMLHttpRequestTimeout) {
1346
- request.reason = 'slow';
1347
- request.detail = "request is too slow, XMLHttpRequestTimeout: ".concat(loadTime);
1348
- }
1349
- else if (status_1 && status_1 >= 300 && statusText && statusText.toLowerCase() !== 'ok') {
1350
- request.reason = 'failed';
1351
- request.detail = "request is failed, status: ".concat(status_1, ", statusText: ").concat(statusText);
1414
+ ws.onclose = function () {
1415
+ ws.close(1000);
1416
+ if (websocketHeartBeatInterval)
1417
+ clearInterval(websocketHeartBeatInterval);
1418
+ websocketHeartBeatInterval = setInterval(reconnectAndSend, 10000);
1419
+ };
1420
+ if (!mounted) {
1421
+ reconnectNetwork();
1422
+ mounted = true;
1423
+ }
1424
+ }
1425
+ };
1426
+ var openWS = function () {
1427
+ var data = getReport();
1428
+ var page = data.page, projectID = data.projectID, host = data.host, pageTitle = data.pageTitle;
1429
+ var msg = {
1430
+ type: WEBSOCKET_TYPE.TRY_CONNECT,
1431
+ userId: userId,
1432
+ platform: 'monitor-track-sdk',
1433
+ data: {
1434
+ p: page,
1435
+ pid: projectID,
1436
+ host: host,
1437
+ pt: pageTitle,
1438
+ platform: 'web'
1439
+ }
1440
+ };
1441
+ wsSendFunc(msg);
1442
+ };
1443
+ var reconnectAndSend = function () {
1444
+ try {
1445
+ if (ws.readyState !== 1) {
1446
+ reconnectSocket();
1447
+ }
1448
+ else {
1449
+ var msg = {
1450
+ type: WEBSOCKET_TYPE.CHECK_CONNECT,
1451
+ userId: userId,
1452
+ data: WEBSOCKET_TYPE.PING,
1453
+ date: Date.now()
1454
+ };
1455
+ wsSendFunc(msg, 'reconnectAndSend');
1456
+ // 20秒超时,如果收不到服务端pong响应则表示服务端已主动断开连接,此时需客户端重新开启websocket连接
1457
+ reconnectAndSendTimeout = setTimeout(function () {
1458
+ reconnectSocket();
1459
+ }, 20000);
1460
+ }
1461
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1462
+ }
1463
+ catch (_err) {
1464
+ // console.error('monitor-track-sdk: reconnectAndSend err', err);
1465
+ }
1466
+ };
1467
+ var closeWebsocket = function (info) {
1468
+ if (ws) {
1469
+ ws.onopen = null;
1470
+ ws.onmessage = null;
1471
+ ws.onerror = null;
1472
+ ws.onclose = null;
1473
+ if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) {
1474
+ ws.close(1000, info);
1475
+ }
1476
+ //@ts-ignore
1477
+ ws = null; // 释放引用
1478
+ }
1479
+ if (websocketHeartBeatInterval)
1480
+ clearInterval(websocketHeartBeatInterval);
1481
+ };
1482
+ var reconnectSocket = function () {
1483
+ // console.warn('monitor-track-sdk: 正在重新建立websocket连接...');
1484
+ initWebsocket();
1485
+ };
1486
+ var incomingMessage = function (e) { return __awaiter(void 0, void 0, void 0, function () {
1487
+ var data, msg, _a, enable, platform, userId_1;
1488
+ return __generator(this, function (_b) {
1489
+ data = {};
1490
+ try {
1491
+ data = JSON.parse(e.data);
1492
+ // console.info('incomingMessage data', data);
1493
+ switch (data.type) {
1494
+ case WEBSOCKET_TYPE.PONG:
1495
+ // console.info('monitor-track-sdk: incomingMessage 响应客户端的心跳: ping => pong');
1496
+ clearTimeout(reconnectAndSendTimeout);
1497
+ break;
1498
+ case WEBSOCKET_TYPE.SOCKET_HEART_BEAT: {
1499
+ msg = {
1500
+ type: WEBSOCKET_TYPE.CHECK_CONNECT,
1501
+ userId: userId,
1502
+ data: WEBSOCKET_TYPE.REPLY_SERVER_HEART_BEAT,
1503
+ date: Date.now()
1504
+ };
1505
+ wsSendFunc(msg, 'socket-heart-beat reply-server-heart-beat');
1506
+ break;
1352
1507
  }
1353
- else ;
1354
- if (request.reason) {
1355
- if (!tempUrlInfo[responseURL_1]) {
1356
- tempUrlInfo[responseURL_1] = true;
1357
- setTimeout(function () {
1358
- delete tempUrlInfo[responseURL_1];
1359
- }, 10);
1360
- setReportValue('error', null);
1361
- report(__assign(__assign({}, getReport()), {
1362
- page: location.href,
1363
- originPage: location.href,
1364
- type: 'request',
1365
- req: request
1366
- }));
1508
+ case WEBSOCKET_TYPE.RESPONSE_DATE:
1509
+ // console.info(`monitor-track-sdk: incomingMessage WS connected, Roundtrip time: ${Date.now() - data.data} ms`);
1510
+ break;
1511
+ case WEBSOCKET_TYPE.REMOTE_DEBUG_ENABLE: {
1512
+ _a = data.data, enable = _a.enable, platform = _a.platform, userId_1 = _a.userId;
1513
+ if (enable && platform && userId_1) {
1514
+ targetPlatform = platform;
1515
+ targetUserId = userId_1;
1516
+ formatConsole();
1517
+ }
1518
+ else {
1519
+ resetConsole();
1367
1520
  }
1521
+ break;
1368
1522
  }
1523
+ case WEBSOCKET_TYPE.REPlY_MESSAGE: {
1524
+ // eslint-disable-next-line no-console
1525
+ console.info('incomingMessage REPlY_MESSAGE, data: ', data.data);
1526
+ break;
1527
+ }
1528
+ default:
1529
+ // console.error('incomingMessage default error', data);
1530
+ break;
1369
1531
  }
1370
- // 当前请求成功后就在数组中移除掉
1371
- timeRecordArray.splice(i, 1);
1372
- };
1373
- for (var i = 0; i < timeRecordArrayCopy.length; i++) {
1374
- _loop_1(i);
1375
1532
  }
1533
+ catch (err) {
1534
+ // eslint-disable-next-line no-console
1535
+ console.error('monitor-track-sdk incomingMessage JSON.parse', err);
1536
+ }
1537
+ return [2 /*return*/];
1376
1538
  });
1539
+ }); };
1540
+ var wsSendFunc = function (msg, _info) {
1541
+ if (ws.readyState === 1) {
1542
+ msg.platform = 'monitor-track-sdk';
1543
+ var message = JSON.stringify(msg);
1544
+ ws.send(message);
1545
+ }
1546
+ else {
1547
+ // console.warn('monitor-track-sdk: window.ws.readyState === 1 info', info);
1548
+ reconnectSocket();
1549
+ }
1377
1550
  };
1378
- var hackFetch = function (XMLHttpRequestTimeout) {
1379
- XMLHttpRequestTimeout = typeof XMLHttpRequestTimeout === 'number' ? XMLHttpRequestTimeout : 1000;
1380
- if (typeof window.fetch === 'function') {
1381
- var __fetch__1 = window.fetch;
1382
- window.__fetch__ = __fetch__1;
1383
- //@ts-ignore
1384
- window.fetch = function (t) {
1385
- var args = [];
1386
- for (var _i = 1; _i < arguments.length; _i++) {
1387
- args[_i - 1] = arguments[_i];
1551
+ var reconnectNetwork = function () {
1552
+ var networkFlag = false;
1553
+ var debounceTimeout = null;
1554
+ document.addEventListener('offline', function () {
1555
+ // 断开网络
1556
+ try {
1557
+ // console.info('monitor-track-sdk: 客户端网络已断开,正在关闭websocket');
1558
+ ws.close(1000);
1559
+ networkFlag = true;
1560
+ debounceTimeout = setTimeout(function () {
1561
+ // console.warn('monitor-track-sdk: reconnectNetwork offline 无法访问网络');
1562
+ // message.error('无法访问网络');
1563
+ }, 5000);
1564
+ }
1565
+ catch (err) {
1566
+ // console.error('monitor-track-sdk: addEventListener offline after setTimeout', err);
1567
+ }
1568
+ }, false);
1569
+ document.addEventListener('online', function () {
1570
+ // 连接到网络
1571
+ try {
1572
+ if (networkFlag === true) {
1573
+ clearTimeout(debounceTimeout);
1574
+ // console.info('monitor-track-sdk: addEventListener reconnectNetwork online');
1575
+ // message.success('网络已恢复');
1576
+ networkFlag = false;
1577
+ // console.warn('monitor-track-sdk: addEventListener online websocket 正在重新建立连接...');
1578
+ initWebsocket();
1388
1579
  }
1389
- var begin = Date.now();
1390
- //禁用数组的扩展运算符,否则portal的生产环境会报Uncaught TypeError: Object(...) is not a function,
1391
- //编译后的__spreadArray函数有问题,而这个函数来自于tslib.具体报错原因不知.
1392
- //其他平台使用数组的扩展运算符没有问题,比如前端监控平台的管理界面
1393
- var params = [].concat(t).concat(args);
1394
- return __fetch__1
1395
- .apply(window, params)
1396
- .then(function (res) {
1397
- var response = res.clone();
1398
- var headers = response.headers;
1399
- if (headers && typeof headers.get === 'function') {
1400
- var ct = headers.get('content-type');
1401
- if (ct && !/(text)|(json)/.test(ct)) {
1402
- return res;
1403
- }
1580
+ }
1581
+ catch (err) {
1582
+ // console.error('monitor-track-sdk: document.addEventListener online', err);
1583
+ }
1584
+ }, false);
1585
+ };
1586
+
1587
+ var xhrTimeout = 2500;
1588
+ var fetchTimeout = 2500;
1589
+ var maxContentLength = 1000;
1590
+ // 保存原始 XMLHttpRequest
1591
+ var OriginalXHR = window.XMLHttpRequest;
1592
+ // 创建增强版的 XMLHttpRequest
1593
+ var InterceptedXHR = /** @class */ (function (_super) {
1594
+ __extends(InterceptedXHR, _super);
1595
+ function InterceptedXHR() {
1596
+ var _this = _super.call(this) || this;
1597
+ _this.requestInfo = {
1598
+ requestType: 'xhr',
1599
+ method: '',
1600
+ responseURL: '',
1601
+ requestData: null,
1602
+ responseBody: null,
1603
+ status: 0,
1604
+ startTime: Date.now(),
1605
+ loadTime: 0,
1606
+ statusText: '',
1607
+ reason: '',
1608
+ detail: ''
1609
+ };
1610
+ _this.setupInterceptors();
1611
+ return _this;
1612
+ }
1613
+ InterceptedXHR.prototype.open = function (method, url, async, username, password) {
1614
+ if (async === void 0) { async = true; }
1615
+ _super.prototype.open.call(this, method, url, async, username, password);
1616
+ this.requestInfo.method = method;
1617
+ this.requestInfo.responseURL = url;
1618
+ };
1619
+ // eslint-disable-next-line no-undef
1620
+ InterceptedXHR.prototype.send = function (body) {
1621
+ _super.prototype.send.call(this, body);
1622
+ try {
1623
+ this.requestInfo.requestData =
1624
+ typeof body === 'object' && body
1625
+ ? JSON.stringify(body).slice(0, maxContentLength)
1626
+ : typeof body === 'string'
1627
+ ? body.slice(0, maxContentLength)
1628
+ : body || '';
1629
+ }
1630
+ catch (err) {
1631
+ // eslint-disable-next-line no-console
1632
+ console.error('xhr send err: ', err, 'body', body);
1633
+ }
1634
+ this.requestInfo.startTime = Date.now();
1635
+ };
1636
+ InterceptedXHR.prototype.setupInterceptors = function () {
1637
+ var _this = this;
1638
+ this.addEventListener('load', function () {
1639
+ try {
1640
+ _this.requestInfo.status = _this.status;
1641
+ _this.requestInfo.responseBody = _this.responseText.slice(0, maxContentLength);
1642
+ _this.requestInfo.loadTime = Date.now() - _this.requestInfo.startTime;
1643
+ _this.requestInfo.statusText = _this.statusText;
1644
+ if (_this.requestInfo.loadTime > xhrTimeout) {
1645
+ _this.requestInfo.reason = 'slow';
1646
+ _this.requestInfo.detail = "request is too slow, XMLHttpRequestTimeout: ".concat(_this.requestInfo.loadTime);
1647
+ }
1648
+ if (_this.status >= 400) {
1649
+ _this.requestInfo.reason = 'failed';
1650
+ _this.requestInfo.detail = "request is failed, status: ".concat(_this.status, ", statusText: ").concat(_this.statusText);
1404
1651
  }
1405
- var loadTime = Date.now() - begin;
1406
- response
1407
- .text()
1408
- .then(function (result) {
1409
- var url = response.url, status = response.status, statusText = response.statusText, ok = response.ok;
1410
- var request = {
1652
+ if (_this.requestInfo.reason) {
1653
+ setReportValue('error', null);
1654
+ report(__assign(__assign({}, getReport()), {
1655
+ page: location.href,
1656
+ originPage: location.href,
1657
+ type: 'request',
1658
+ req: _this.requestInfo
1659
+ }));
1660
+ }
1661
+ uploadRequest(_this.requestInfo);
1662
+ }
1663
+ catch (err) {
1664
+ // eslint-disable-next-line no-console
1665
+ console.error('xhr load err: ', err, 'this.requestInfo', _this.requestInfo);
1666
+ }
1667
+ });
1668
+ this.addEventListener('error', function () {
1669
+ // console.error('❌ 请求失败:', this.requestInfo);
1670
+ });
1671
+ };
1672
+ return InterceptedXHR;
1673
+ }(OriginalXHR));
1674
+ var recordXMLHttpRequest = function (XMLHttpRequestTimeout) {
1675
+ xhrTimeout = XMLHttpRequestTimeout;
1676
+ // 重写全局 XMLHttpRequest
1677
+ window.XMLHttpRequest = InterceptedXHR;
1678
+ };
1679
+ var originalFetch = window.fetch;
1680
+ // eslint-disable-next-line no-undef
1681
+ var fetchFUnc = function (input, init) {
1682
+ return __awaiter(this, void 0, void 0, function () {
1683
+ var url, options, requestInfo, response, clonedResponse, responseBody, e_1, err_1;
1684
+ return __generator(this, function (_a) {
1685
+ switch (_a.label) {
1686
+ case 0:
1687
+ url = typeof input === 'string' ? input : input.toString();
1688
+ options = init || {};
1689
+ requestInfo = {
1411
1690
  requestType: 'fetch',
1691
+ method: options.method || 'GET',
1412
1692
  responseURL: url,
1413
- status: status,
1414
- loadTime: loadTime,
1415
- statusText: statusText,
1693
+ requestData: typeof options.body === 'object' && options.body ? JSON.stringify(options.body).slice(0, maxContentLength) : options.body || '',
1694
+ responseBody: '',
1695
+ status: 0,
1696
+ startTime: Date.now(),
1697
+ loadTime: 0,
1698
+ statusText: '',
1416
1699
  reason: '',
1417
- detail: '',
1418
- requestData: '',
1419
- method: ''
1700
+ detail: ''
1420
1701
  };
1421
- if (!ok || status >= 300) {
1422
- request.reason = 'failed';
1423
- request.detail = "request is failed, status: ".concat(status, ", statusText: ").concat(statusText);
1424
- }
1425
- else if (loadTime > XMLHttpRequestTimeout) {
1426
- request.reason = 'slow';
1427
- request.detail = "request is too slow, XMLHttpRequestTimeout: ".concat(loadTime, ", result: ").concat(result === null || result === void 0 ? void 0 : result.slice(0, 500));
1702
+ return [4 /*yield*/, originalFetch(input, init)];
1703
+ case 1:
1704
+ response = _a.sent();
1705
+ _a.label = 2;
1706
+ case 2:
1707
+ _a.trys.push([2, 7, , 8]);
1708
+ clonedResponse = response.clone();
1709
+ requestInfo.status = response.status;
1710
+ requestInfo.loadTime = Date.now() - requestInfo.startTime;
1711
+ requestInfo.statusText = response.statusText;
1712
+ if (!response.ok) {
1713
+ requestInfo.reason = 'failed';
1714
+ requestInfo.detail = "request is failed, status: ".concat(response.status, ", statusText: ").concat(response.statusText);
1428
1715
  }
1429
- if (request.reason) {
1430
- if (!tempUrlInfo[url]) {
1431
- tempUrlInfo[url] = true;
1432
- setTimeout(function () {
1433
- delete tempUrlInfo[url];
1434
- }, 10);
1435
- setReportValue('error', null);
1436
- report(__assign(__assign({}, getReport()), {
1437
- page: location.href,
1438
- originPage: location.href,
1439
- type: 'request',
1440
- req: request
1441
- }));
1716
+ else {
1717
+ if (requestInfo.loadTime > fetchTimeout) {
1718
+ requestInfo.reason = 'slow';
1719
+ requestInfo.detail = "request is too slow, XMLHttpRequestTimeout: ".concat(requestInfo.loadTime);
1442
1720
  }
1443
1721
  }
1444
- })["catch"](function (err) {
1722
+ _a.label = 3;
1723
+ case 3:
1724
+ _a.trys.push([3, 5, , 6]);
1725
+ return [4 /*yield*/, clonedResponse.text()];
1726
+ case 4:
1727
+ responseBody = _a.sent();
1728
+ requestInfo.responseBody = responseBody.slice(0, maxContentLength);
1729
+ return [3 /*break*/, 6];
1730
+ case 5:
1731
+ e_1 = _a.sent();
1732
+ requestInfo.responseBody = (e_1 === null || e_1 === void 0 ? void 0 : e_1.message) || (e_1 === null || e_1 === void 0 ? void 0 : e_1.stack) || (e_1 === null || e_1 === void 0 ? void 0 : e_1.toString());
1733
+ return [3 /*break*/, 6];
1734
+ case 6:
1735
+ if (requestInfo.reason) {
1736
+ setReportValue('error', null);
1737
+ report(__assign(__assign({}, getReport()), {
1738
+ page: location.href,
1739
+ originPage: location.href,
1740
+ type: 'request',
1741
+ req: requestInfo
1742
+ }));
1743
+ }
1744
+ uploadRequest(requestInfo);
1745
+ return [3 /*break*/, 8];
1746
+ case 7:
1747
+ err_1 = _a.sent();
1445
1748
  // eslint-disable-next-line no-console
1446
- console.log('hackFetch response.text() err', err);
1447
- });
1448
- return res;
1449
- })["catch"](function (err) {
1450
- // eslint-disable-next-line no-console
1451
- console.log('hackFetch err', err);
1452
- });
1453
- };
1454
- }
1749
+ console.error(' 获取响应数据失败, requestInfo: ', requestInfo, 'err: ', err_1);
1750
+ return [3 /*break*/, 8];
1751
+ case 8: return [2 /*return*/, response];
1752
+ }
1753
+ });
1754
+ });
1755
+ };
1756
+ var recordFetch = function (XMLHttpRequestTimeout) {
1757
+ fetchTimeout = XMLHttpRequestTimeout;
1758
+ window.fetch = fetchFUnc;
1455
1759
  };
1456
1760
 
1457
1761
  var Track = /** @class */ (function () {
@@ -1478,7 +1782,6 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
1478
1782
  };
1479
1783
  }
1480
1784
  Track.prototype.init = function (config) {
1481
- var _a;
1482
1785
  // 是否开启日志收集
1483
1786
  if (!config || !config.enable) {
1484
1787
  return;
@@ -1495,19 +1798,17 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
1495
1798
  console.warn('缺少上报地址!');
1496
1799
  return;
1497
1800
  }
1498
- if (this.ignoreUrl(((_a = config === null || config === void 0 ? void 0 : config.ignore) === null || _a === void 0 ? void 0 : _a.urls) || [])) {
1499
- return;
1500
- }
1501
1801
  setConfig(config);
1502
1802
  initReport();
1503
- recordXMLHttpRequestLog(config.XMLHttpRequestTimeout);
1504
- hackFetch(config.XMLHttpRequestTimeout);
1803
+ recordXMLHttpRequest(config.XMLHttpRequestTimeout || 2500);
1804
+ recordFetch(config.XMLHttpRequestTimeout || 2500);
1505
1805
  Config.spa && this.addListenRouterChange();
1506
1806
  Config.enableBehavior && this.addListenUserActivity();
1507
1807
  Config.enableError && this.addListenJSUncaught();
1508
1808
  Config.enableVisualTrack && this.visualTrack();
1509
1809
  Config.enableLagTrack && this.listenPageLag();
1510
1810
  Config.enableRecord && enableRecordFunc();
1811
+ Config.enableOnlinePersons && enableOnlinePersonsFunc();
1511
1812
  this.addListenUnload();
1512
1813
  initWindowObjectFunction();
1513
1814
  };
@@ -1548,14 +1849,6 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
1548
1849
  _this.destroy();
1549
1850
  });
1550
1851
  };
1551
- /**
1552
- * 忽略的url
1553
- * @param urls
1554
- */
1555
- Track.prototype.ignoreUrl = function (urls) {
1556
- var someUrl = urls.some(function (url) { return location.href.includes(url); });
1557
- return someUrl;
1558
- };
1559
1852
  /**
1560
1853
  * @description 销毁监听器
1561
1854
  */
@@ -1578,6 +1871,7 @@ var MonitorTrack = (function (uuid, ErrorStackParser, html2canvas, rrweb, axios,
1578
1871
  this.lagTimer && clearInterval(this.lagTimer);
1579
1872
  (_a = this.observer) === null || _a === void 0 ? void 0 : _a.disconnect();
1580
1873
  sessionStorage.removeItem(monitorTrackSessionId);
1874
+ closeWebsocket('destroy');
1581
1875
  };
1582
1876
  return Track;
1583
1877
  }());