|
1 | 1 | import type { listenerHandler, RecordPlugin, IWindow } from '@rrweb/types';
|
2 | 2 | import { patch } from '@rrweb/utils';
|
3 | 3 |
|
4 |
| -function findLast<T>( |
5 |
| - array: Array<T>, |
6 |
| - predicate: (value: T) => boolean, |
7 |
| -): T | undefined { |
8 |
| - const length = array.length; |
9 |
| - for (let i = length - 1; i >= 0; i -= 1) { |
10 |
| - if (predicate(array[i])) { |
11 |
| - return array[i]; |
12 |
| - } |
13 |
| - } |
14 |
| -} |
15 |
| - |
16 | 4 | export type InitiatorType =
|
17 | 5 | | 'audio'
|
18 | 6 | | 'beacon'
|
@@ -89,12 +77,17 @@ type Body =
|
89 | 77 | | ReadableStream<Uint8Array>
|
90 | 78 | | null;
|
91 | 79 |
|
92 |
| -type NetworkRequest = Omit<PerformanceEntry, 'toJSON'> & { |
| 80 | +type NetworkRequest = Omit< |
| 81 | + PerformanceEntry, |
| 82 | + 'toJSON' | 'startTime' | 'endTime' | 'duration' | 'entryType' |
| 83 | +> & { |
93 | 84 | method?: string;
|
94 | 85 | initiatorType?: InitiatorType;
|
95 | 86 | status?: number;
|
96 | 87 | startTime?: number;
|
97 | 88 | endTime?: number;
|
| 89 | + duration?: number; |
| 90 | + entryType?: string; |
98 | 91 | requestHeaders?: Headers;
|
99 | 92 | requestBody?: Body;
|
100 | 93 | responseHeaders?: Headers;
|
@@ -345,22 +338,23 @@ function initXhrObserver(
|
345 | 338 | before,
|
346 | 339 | )
|
347 | 340 | .then((entry) => {
|
348 |
| - if (!entry) return; |
349 |
| - const request: NetworkRequest = { |
350 |
| - method: req.method, |
351 |
| - initiatorType: entry.initiatorType as InitiatorType, |
352 |
| - duration: entry.duration, |
353 |
| - entryType: entry.entryType, |
354 |
| - name: entry.name, |
355 |
| - status: xhr.status, |
356 |
| - startTime: Math.round(entry.startTime), |
357 |
| - endTime: Math.round(entry.responseEnd), |
358 |
| - requestHeaders: networkRequest.requestHeaders, |
359 |
| - requestBody: networkRequest.requestBody, |
360 |
| - responseHeaders: networkRequest.responseHeaders, |
361 |
| - responseBody: networkRequest.responseBody, |
362 |
| - }; |
363 |
| - cb({ requests: [request] }); |
| 341 | + if (!entry) { |
| 342 | + // https://github.com/rrweb-io/rrweb/pull/1105#issuecomment-1953808336 |
| 343 | + const requests = prepareRequestWithoutPerformance( |
| 344 | + req, |
| 345 | + networkRequest, |
| 346 | + ); |
| 347 | + cb({ requests }); |
| 348 | + return; |
| 349 | + } |
| 350 | + |
| 351 | + const requests = prepareRequest( |
| 352 | + entry, |
| 353 | + req.method, |
| 354 | + xhr.status, |
| 355 | + networkRequest, |
| 356 | + ); |
| 357 | + cb({ requests }); |
364 | 358 | })
|
365 | 359 | .catch(() => {
|
366 | 360 | //
|
@@ -446,22 +440,23 @@ function initFetchObserver(
|
446 | 440 | } finally {
|
447 | 441 | getRequestPerformanceEntry(win, 'fetch', req.url, after, before)
|
448 | 442 | .then((entry) => {
|
449 |
| - if (!entry) return; |
450 |
| - const request: NetworkRequest = { |
451 |
| - method: req.method, |
452 |
| - initiatorType: entry.initiatorType as InitiatorType, |
453 |
| - duration: entry.duration, |
454 |
| - entryType: entry.entryType, |
455 |
| - name: entry.name, |
456 |
| - status: res?.status, |
457 |
| - startTime: Math.round(entry.startTime), |
458 |
| - endTime: Math.round(entry.responseEnd), |
459 |
| - requestHeaders: networkRequest.requestHeaders, |
460 |
| - requestBody: networkRequest.requestBody, |
461 |
| - responseHeaders: networkRequest.responseHeaders, |
462 |
| - responseBody: networkRequest.responseBody, |
463 |
| - }; |
464 |
| - cb({ requests: [request] }); |
| 443 | + if (!entry) { |
| 444 | + // https://github.com/rrweb-io/rrweb/pull/1105#issuecomment-1953808336 |
| 445 | + const requests = prepareRequestWithoutPerformance( |
| 446 | + req, |
| 447 | + networkRequest, |
| 448 | + ); |
| 449 | + cb({ requests }); |
| 450 | + return; |
| 451 | + } |
| 452 | + |
| 453 | + const requests = prepareRequest( |
| 454 | + entry, |
| 455 | + req.method, |
| 456 | + res?.status, |
| 457 | + networkRequest, |
| 458 | + ); |
| 459 | + cb({ requests }); |
465 | 460 | })
|
466 | 461 | .catch(() => {
|
467 | 462 | //
|
@@ -509,6 +504,58 @@ function initNetworkObserver(
|
509 | 504 | };
|
510 | 505 | }
|
511 | 506 |
|
| 507 | +function prepareRequest( |
| 508 | + entry: PerformanceResourceTiming, |
| 509 | + method: string | undefined, |
| 510 | + status: number | undefined, |
| 511 | + networkRequest: Partial<NetworkRequest>, |
| 512 | +): NetworkRequest[] { |
| 513 | + const request: NetworkRequest = { |
| 514 | + method, |
| 515 | + initiatorType: entry.initiatorType as InitiatorType, |
| 516 | + duration: entry.duration, |
| 517 | + entryType: entry.entryType, |
| 518 | + name: entry.name, |
| 519 | + status, |
| 520 | + startTime: Math.round(entry.startTime), |
| 521 | + endTime: Math.round(entry.responseEnd), |
| 522 | + requestHeaders: networkRequest.requestHeaders, |
| 523 | + requestBody: networkRequest.requestBody, |
| 524 | + responseHeaders: networkRequest.responseHeaders, |
| 525 | + responseBody: networkRequest.responseBody, |
| 526 | + }; |
| 527 | + |
| 528 | + return [request]; |
| 529 | +} |
| 530 | + |
| 531 | +function prepareRequestWithoutPerformance( |
| 532 | + req: Request, |
| 533 | + networkRequest: Partial<NetworkRequest>, |
| 534 | +): NetworkRequest[] { |
| 535 | + const request: NetworkRequest = { |
| 536 | + name: req.url, |
| 537 | + method: req.method, |
| 538 | + requestHeaders: networkRequest.requestHeaders, |
| 539 | + requestBody: networkRequest.requestBody, |
| 540 | + responseHeaders: networkRequest.responseHeaders, |
| 541 | + responseBody: networkRequest.responseBody, |
| 542 | + }; |
| 543 | + |
| 544 | + return [request]; |
| 545 | +} |
| 546 | + |
| 547 | +function findLast<T>( |
| 548 | + array: Array<T>, |
| 549 | + predicate: (value: T) => boolean, |
| 550 | +): T | undefined { |
| 551 | + const length = array.length; |
| 552 | + for (let i = length - 1; i >= 0; i -= 1) { |
| 553 | + if (predicate(array[i])) { |
| 554 | + return array[i]; |
| 555 | + } |
| 556 | + } |
| 557 | +} |
| 558 | + |
512 | 559 | export const PLUGIN_NAME = 'rrweb/network@1';
|
513 | 560 |
|
514 | 561 | export const getRecordNetworkPlugin: (
|
|
0 commit comments