Skip to content

Commit 5223ce4

Browse files
committed
chore: fixes pr comments
1 parent e9cd8fe commit 5223ce4

File tree

2 files changed

+42
-30
lines changed

2 files changed

+42
-30
lines changed

docs/recipes/network.md

+14-14
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ rrweb.record({
4242
plugins: [
4343
getRecordNetworkPlugin({
4444
initiatorTypes: ['fetch', 'xmlhttprequest'],
45-
// block recording event for request to upload events to server
46-
ignoreRequestFn: (request) => {
47-
if (request.url === 'https://api.my-server.com/events') {
48-
return true;
49-
}
50-
return false;
45+
// transform recording event for request to block or mask
46+
transformRequestFn: (request) => {
47+
if (request.url.contains("rrweb-collector-api.com")) return; // skip request
48+
delete request.requestHeaders["Authorization"]; // remove sensetive data
49+
request.responseBody = maskTextFn(request.responseBody);
50+
return request;
5151
},
5252
recordHeaders: true,
5353
recordBody: true,
@@ -57,17 +57,17 @@ rrweb.record({
5757
});
5858
```
5959

60-
**alert**: If you are uploading events to a server, you should always use `ignoreRequestFn` to block recording events for these requests or else you will cause a nasty loop.
60+
**alert**: If you are uploading events to a server, you should always use `transformRequestFn` to transform/block recording events for these requests or else you will cause a nasty loop.
6161

6262
All options are described below:
6363

64-
| key | default | description |
65-
| ---------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
66-
| initiatorTypes | `['fetch','xmlhttprequest','img',...]` | Default value contains names of all [initiator types](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/initiatorType). You can override it by setting the types you need. |
67-
| ignoreRequestFn | `() => false` | Block recording events for specific requests |
68-
| recordHeaders | `false` | Record the request & response headers for `fetch` and `xmlhttprequest` requests |
69-
| recordBody | `false` | Record the request & response bodies for `fetch` and `xmlhttprequest` requests |
70-
| recordInitialRequests | `false` | Record an event for all requests prior to rrweb.record() being called |
64+
| key | default | description |
65+
| ---------------- |--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
66+
| initiatorTypes | `['fetch','xmlhttprequest','img',...]` | Default value contains names of all [initiator types](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/initiatorType). You can override it by setting the types you need. |
67+
| transformRequestFn | `(request) => request` | Transform recording event for request to block (skip) or mask/transofrm request (e.g. to hide sensetive data) |
68+
| recordHeaders | `false` | Record the request & response headers for `fetch` and `xmlhttprequest` requests |
69+
| recordBody | `false` | Record the request & response bodies for `fetch` and `xmlhttprequest` requests |
70+
| recordInitialRequests | `false` | Record an event for all requests prior to rrweb.record() being called |
7171

7272
## replay network
7373

packages/plugins/rrweb-plugin-network-record/src/index.ts

+28-16
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export type InitiatorType =
3838

3939
type NetworkRecordOptions = {
4040
initiatorTypes?: InitiatorType[];
41-
ignoreRequestFn?: (data: NetworkRequest) => boolean;
41+
maskRequestFn?: (request: NetworkRequest) => NetworkRequest | undefined;
4242
recordHeaders?: boolean | { request: boolean; response: boolean };
4343
recordBody?:
4444
| boolean
@@ -71,7 +71,7 @@ const defaultNetworkOptions: NetworkRecordOptions = {
7171
'video',
7272
'xmlhttprequest',
7373
],
74-
ignoreRequestFn: () => false,
74+
maskRequestFn: (request) => request,
7575
recordHeaders: false,
7676
recordBody: false,
7777
recordInitialRequests: false,
@@ -89,17 +89,18 @@ type Body =
8989
| ReadableStream<Uint8Array>
9090
| null;
9191

92-
type NetworkRequest = {
93-
url: string;
92+
type NetworkRequest = Omit<PerformanceEntry, 'toJSON'> & {
9493
method?: string;
95-
initiatorType: InitiatorType;
94+
initiatorType?: InitiatorType;
9695
status?: number;
97-
startTime: number;
98-
endTime: number;
96+
startTime?: number;
97+
endTime?: number;
9998
requestHeaders?: Headers;
10099
requestBody?: Body;
101100
responseHeaders?: Headers;
102101
responseBody?: Body;
102+
// was this captured before fetch/xhr could have been wrapped
103+
isInitial?: boolean;
103104
};
104105

105106
export type NetworkData = {
@@ -141,8 +142,10 @@ function initPerformanceObserver(
141142
);
142143
cb({
143144
requests: initialPerformanceEntries.map((entry) => ({
144-
url: entry.name,
145145
initiatorType: entry.initiatorType as InitiatorType,
146+
duration: entry.duration,
147+
entryType: entry.entryType,
148+
name: entry.name,
146149
status: 'responseStatus' in entry ? entry.responseStatus : undefined,
147150
startTime: Math.round(entry.startTime),
148151
endTime: Math.round(entry.responseEnd),
@@ -165,11 +168,13 @@ function initPerformanceObserver(
165168
);
166169
cb({
167170
requests: performanceEntries.map((entry) => ({
168-
url: entry.name,
169171
initiatorType: entry.initiatorType as InitiatorType,
170172
status: 'responseStatus' in entry ? entry.responseStatus : undefined,
171173
startTime: Math.round(entry.startTime),
172174
endTime: Math.round(entry.responseEnd),
175+
duration: entry.duration,
176+
entryType: entry.entryType,
177+
name: entry.name,
173178
})),
174179
});
175180
});
@@ -216,9 +221,9 @@ async function getRequestPerformanceEntry(
216221
after?: number,
217222
before?: number,
218223
attempt = 0,
219-
): Promise<PerformanceResourceTiming> {
224+
): Promise<PerformanceResourceTiming | null> {
220225
if (attempt > 10) {
221-
throw new Error('Cannot find performance entry');
226+
return null;
222227
}
223228
const urlPerformanceEntries = win.performance.getEntriesByName(
224229
url,
@@ -340,10 +345,13 @@ function initXhrObserver(
340345
before,
341346
)
342347
.then((entry) => {
348+
if (!entry) return;
343349
const request: NetworkRequest = {
344-
url: entry.name,
345350
method: req.method,
346351
initiatorType: entry.initiatorType as InitiatorType,
352+
duration: entry.duration,
353+
entryType: entry.entryType,
354+
name: entry.name,
347355
status: xhr.status,
348356
startTime: Math.round(entry.startTime),
349357
endTime: Math.round(entry.responseEnd),
@@ -438,10 +446,13 @@ function initFetchObserver(
438446
} finally {
439447
getRequestPerformanceEntry(win, 'fetch', req.url, after, before)
440448
.then((entry) => {
449+
if (!entry) return;
441450
const request: NetworkRequest = {
442-
url: entry.name,
443451
method: req.method,
444452
initiatorType: entry.initiatorType as InitiatorType,
453+
duration: entry.duration,
454+
entryType: entry.entryType,
455+
name: entry.name,
445456
status: res?.status,
446457
startTime: Math.round(entry.startTime),
447458
endTime: Math.round(entry.responseEnd),
@@ -480,9 +491,10 @@ function initNetworkObserver(
480491
) as Required<NetworkRecordOptions>;
481492

482493
const cb: networkCallback = (data) => {
483-
const requests = data.requests.filter(
484-
(request) => !networkOptions.ignoreRequestFn(request),
485-
);
494+
const requests = data.requests
495+
.map((request) => networkOptions.maskRequestFn(request))
496+
.filter(Boolean) as NetworkRequest[];
497+
486498
if (requests.length > 0 || data.isInitial) {
487499
callback({ ...data, requests });
488500
}

0 commit comments

Comments
 (0)