Skip to content

Commit

Permalink
rrweb sends message to cross-origin iframe to force snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
mdellanoce authored and colingm committed May 1, 2024
1 parent f1e6a51 commit debf898
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/rotten-squids-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'rrweb': patch
---

rrweb sends message to cross-origin iframe to force snapshot
28 changes: 26 additions & 2 deletions packages/rrweb/src/record/iframe-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class IframeManager {
private mirror: Mirror;
private mutationCb: mutationCallBack;
private wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;
private takeFullSnapshot: (isCheckout?: boolean) => void;
private loadListener?: (iframeEl: HTMLIFrameElement) => unknown;
private stylesheetManager: StylesheetManager;
private recordCrossOriginIframes: boolean;
Expand All @@ -31,9 +32,11 @@ export class IframeManager {
stylesheetManager: StylesheetManager;
recordCrossOriginIframes: boolean;
wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;
takeFullSnapshot: (isCheckout?: boolean) => void;
}) {
this.mutationCb = options.mutationCb;
this.wrappedEmit = options.wrappedEmit;
this.takeFullSnapshot = options.takeFullSnapshot;
this.stylesheetManager = options.stylesheetManager;
this.recordCrossOriginIframes = options.recordCrossOriginIframes;
this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(
Expand All @@ -51,6 +54,16 @@ export class IframeManager {
this.iframes.set(iframeEl, true);
if (iframeEl.contentWindow)
this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);

if (!iframeEl.contentDocument && iframeEl.contentWindow)
iframeEl.contentWindow.postMessage(
{
type: 'rrweb',
origin: window.location.origin,
snapshot: true,
},
'*',
);
}

public addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown) {
Expand Down Expand Up @@ -95,10 +108,21 @@ export class IframeManager {
)
return;

const iframeSourceWindow = message.source;
const iframeSourceWindow = crossOriginMessageEvent.source;
if (!iframeSourceWindow) return;

const iframeEl = this.crossOriginIframeMap.get(message.source);
if (
iframeSourceWindow == window.parent &&
window != window.parent &&
crossOriginMessageEvent.data.snapshot
) {
this.takeFullSnapshot();
return;
}

const iframeEl = this.crossOriginIframeMap.get(
crossOriginMessageEvent.source,
);
if (!iframeEl) return;

const transformedEvent = this.transformCrossOriginEvent(
Expand Down
1 change: 1 addition & 0 deletions packages/rrweb/src/record/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ function record<T = eventWithTime>(
stylesheetManager: stylesheetManager,
recordCrossOriginIframes,
wrappedEmit,
takeFullSnapshot,
});

/**
Expand Down
1 change: 1 addition & 0 deletions packages/rrweb/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ export type CrossOriginIframeMessageEventContent<T = eventWithTime> = {
// 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.
origin: string;
isCheckout?: boolean;
snapshot?: boolean;
};
export type CrossOriginIframeMessageEvent =
MessageEvent<CrossOriginIframeMessageEventContent>;
Expand Down

0 comments on commit debf898

Please sign in to comment.