fix: some nested cross-origin iframes can't be recorded (#1353)
* fix: some nested cross-origin iframes can't be recorded * fix building error in rrweb-player * add test case for this special case * Apply formatting changes --------- Co-authored-by: YunFeng0817 <YunFeng0817@users.noreply.github.com>
This commit is contained in:
5
.changeset/purple-carrots-film.md
Normal file
5
.changeset/purple-carrots-film.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"rrweb": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix: some nested cross-origin iframes can't be recorded
|
||||||
@@ -74,6 +74,14 @@ export class IframeManager {
|
|||||||
attributes: [],
|
attributes: [],
|
||||||
isAttachIframe: true,
|
isAttachIframe: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Receive messages (events) coming from cross-origin iframes that are nested in this same-origin iframe.
|
||||||
|
if (this.recordCrossOriginIframes)
|
||||||
|
iframeEl.contentWindow?.addEventListener(
|
||||||
|
'message',
|
||||||
|
this.handleMessage.bind(this),
|
||||||
|
);
|
||||||
|
|
||||||
this.loadListener?.(iframeEl);
|
this.loadListener?.(iframeEl);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -5369,3 +5369,273 @@ exports[`same origin iframes > should emit contents of iframe once 1`] = `
|
|||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`same origin iframes should record cross-origin iframe in same-origin iframe 1`] = `
|
||||||
|
"[
|
||||||
|
{
|
||||||
|
\\"type\\": 4,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"href\\": \\"about:blank\\",
|
||||||
|
\\"width\\": 1920,
|
||||||
|
\\"height\\": 1080
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 0,
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 1,
|
||||||
|
\\"name\\": \\"html\\",
|
||||||
|
\\"publicId\\": \\"\\",
|
||||||
|
\\"systemId\\": \\"\\",
|
||||||
|
\\"id\\": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"html\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"head\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"script\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"type\\": \\"text/javascript\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||||
|
\\"id\\": 6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"body\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"iframe\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\\\n \\\\n \\",
|
||||||
|
\\"id\\": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 1
|
||||||
|
},
|
||||||
|
\\"initialOffset\\": {
|
||||||
|
\\"left\\": 0,
|
||||||
|
\\"top\\": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 0,
|
||||||
|
\\"adds\\": [
|
||||||
|
{
|
||||||
|
\\"parentId\\": 9,
|
||||||
|
\\"nextId\\": null,
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 0,
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"html\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"head\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"rootId\\": 11,
|
||||||
|
\\"id\\": 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"body\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"rootId\\": 11,
|
||||||
|
\\"id\\": 14
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"rootId\\": 11,
|
||||||
|
\\"id\\": 12
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"compatMode\\": \\"BackCompat\\",
|
||||||
|
\\"id\\": 11
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"removes\\": [],
|
||||||
|
\\"texts\\": [],
|
||||||
|
\\"attributes\\": [],
|
||||||
|
\\"isAttachIframe\\": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 0,
|
||||||
|
\\"texts\\": [],
|
||||||
|
\\"attributes\\": [],
|
||||||
|
\\"removes\\": [],
|
||||||
|
\\"adds\\": [
|
||||||
|
{
|
||||||
|
\\"parentId\\": 13,
|
||||||
|
\\"nextId\\": null,
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"script\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"type\\": \\"text/javascript\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"rootId\\": 11,
|
||||||
|
\\"id\\": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"parentId\\": 15,
|
||||||
|
\\"nextId\\": null,
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||||
|
\\"rootId\\": 11,
|
||||||
|
\\"id\\": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 0,
|
||||||
|
\\"texts\\": [],
|
||||||
|
\\"attributes\\": [],
|
||||||
|
\\"removes\\": [],
|
||||||
|
\\"adds\\": [
|
||||||
|
{
|
||||||
|
\\"parentId\\": 14,
|
||||||
|
\\"nextId\\": null,
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"iframe\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"rootId\\": 11,
|
||||||
|
\\"id\\": 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 0,
|
||||||
|
\\"adds\\": [
|
||||||
|
{
|
||||||
|
\\"parentId\\": 17,
|
||||||
|
\\"nextId\\": null,
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 0,
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"html\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"head\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"script\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"type\\": \\"text/javascript\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||||
|
\\"rootId\\": 18,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"rootId\\": 18,
|
||||||
|
\\"id\\": 21
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"rootId\\": 18,
|
||||||
|
\\"id\\": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"body\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n\\\\n\\",
|
||||||
|
\\"rootId\\": 18,
|
||||||
|
\\"id\\": 24
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"rootId\\": 18,
|
||||||
|
\\"id\\": 23
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"rootId\\": 18,
|
||||||
|
\\"id\\": 19
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"compatMode\\": \\"BackCompat\\",
|
||||||
|
\\"id\\": 18
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"removes\\": [],
|
||||||
|
\\"texts\\": [],
|
||||||
|
\\"attributes\\": [],
|
||||||
|
\\"isAttachIframe\\": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
`;
|
||||||
|
|||||||
@@ -594,4 +594,28 @@ describe('same origin iframes', function (this: ISuite) {
|
|||||||
expect(events.length).toBe(4);
|
expect(events.length).toBe(4);
|
||||||
assertSnapshot(events);
|
assertSnapshot(events);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should record cross-origin iframe in same-origin iframe', async () => {
|
||||||
|
const sameOriginIframe = ctx.page.mainFrame().childFrames()[0];
|
||||||
|
await sameOriginIframe.evaluate((serverUrl) => {
|
||||||
|
/**
|
||||||
|
* Create a cross-origin iframe in this same-origin iframe.
|
||||||
|
*/
|
||||||
|
const crossOriginIframe = document.createElement('iframe');
|
||||||
|
document.body.appendChild(crossOriginIframe);
|
||||||
|
crossOriginIframe.src = `${serverUrl}/html/blank.html`;
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
crossOriginIframe.onload = resolve;
|
||||||
|
});
|
||||||
|
}, ctx.serverURL);
|
||||||
|
const crossOriginIframe = sameOriginIframe.childFrames()[0];
|
||||||
|
// Inject recording script into this cross-origin iframe
|
||||||
|
await injectRecordScript(crossOriginIframe);
|
||||||
|
|
||||||
|
await waitForRAF(ctx.page);
|
||||||
|
const snapshots = (await ctx.page.evaluate(
|
||||||
|
'window.snapshots',
|
||||||
|
)) as eventWithTime[];
|
||||||
|
assertSnapshot(snapshots);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user