Skip to content

Commit fa0208e

Browse files
mdellanocecolingm
authored andcommitted
rrweb sends message to cross-origin iframe to force snapshot
1 parent f1e6a51 commit fa0208e

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

packages/rrweb/src/record/iframe-manager.ts

+26-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export class IframeManager {
2121
private mirror: Mirror;
2222
private mutationCb: mutationCallBack;
2323
private wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;
24+
private takeFullSnapshot: (isCheckout?: boolean) => void;
2425
private loadListener?: (iframeEl: HTMLIFrameElement) => unknown;
2526
private stylesheetManager: StylesheetManager;
2627
private recordCrossOriginIframes: boolean;
@@ -31,9 +32,11 @@ export class IframeManager {
3132
stylesheetManager: StylesheetManager;
3233
recordCrossOriginIframes: boolean;
3334
wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;
35+
takeFullSnapshot: (isCheckout?: boolean) => void;
3436
}) {
3537
this.mutationCb = options.mutationCb;
3638
this.wrappedEmit = options.wrappedEmit;
39+
this.takeFullSnapshot = options.takeFullSnapshot;
3740
this.stylesheetManager = options.stylesheetManager;
3841
this.recordCrossOriginIframes = options.recordCrossOriginIframes;
3942
this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(
@@ -51,6 +54,16 @@ export class IframeManager {
5154
this.iframes.set(iframeEl, true);
5255
if (iframeEl.contentWindow)
5356
this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);
57+
58+
if (!iframeEl.contentDocument && iframeEl.contentWindow)
59+
iframeEl.contentWindow.postMessage(
60+
{
61+
type: 'rrweb',
62+
origin: window.location.origin,
63+
snapshot: true,
64+
},
65+
'*',
66+
);
5467
}
5568

5669
public addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown) {
@@ -95,10 +108,21 @@ export class IframeManager {
95108
)
96109
return;
97110

98-
const iframeSourceWindow = message.source;
111+
const iframeSourceWindow = crossOriginMessageEvent.source;
99112
if (!iframeSourceWindow) return;
100113

101-
const iframeEl = this.crossOriginIframeMap.get(message.source);
114+
if (
115+
iframeSourceWindow == window.parent &&
116+
window != window.parent &&
117+
crossOriginMessageEvent.data.snapshot
118+
) {
119+
this.takeFullSnapshot();
120+
return;
121+
}
122+
123+
const iframeEl = this.crossOriginIframeMap.get(
124+
crossOriginMessageEvent.source,
125+
);
102126
if (!iframeEl) return;
103127

104128
const transformedEvent = this.transformCrossOriginEvent(

packages/rrweb/src/record/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ function record<T = eventWithTime>(
278278
stylesheetManager: stylesheetManager,
279279
recordCrossOriginIframes,
280280
wrappedEmit,
281+
takeFullSnapshot,
281282
});
282283

283284
/**

packages/rrweb/src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export type CrossOriginIframeMessageEventContent<T = eventWithTime> = {
216216
// The origin of the iframe which originally emits this message. It is used to check the integrity of message and to filter out the rrweb messages which are forwarded by some sites.
217217
origin: string;
218218
isCheckout?: boolean;
219+
snapshot?: boolean;
219220
};
220221
export type CrossOriginIframeMessageEvent =
221222
MessageEvent<CrossOriginIframeMessageEventContent>;

0 commit comments

Comments
 (0)