Skip to content

Commit 4a5e4cf

Browse files
committed
Docs: AI translated, cross origin iframe recording
1 parent f3705b3 commit 4a5e4cf

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Cross origin iframes
2+
3+
默认情况下,浏览器很难访问托管在不同域上的 iframe 的内容。 这是一项安全功能,可防止恶意站点访问其他站点上的敏感信息。 可以解决此安全功能。
4+
但不建议这样做,除非您非常严格 https://stackoverflow.com/a/21629575 只允许您信任的网站将您的网站嵌入 iframe 中。
5+
因为如果您允许记录跨源 iframe,任何恶意网站都可以嵌入您的网站,并且只要它们运行 rrweb,它们就可以记录您网站的所有内容。
6+
7+
## 如何记录跨源 iframe
8+
9+
在父页面中启用录制跨域 iframe:
10+
11+
```js
12+
rrweb.record({
13+
emit(event) {}, // 所有事件都将在此处发出,包括来自跨源 iframe 的事件
14+
recordCrossOriginIframes: true,
15+
});
16+
```
17+
18+
在您的子页面中启用重放跨域 iframe:
19+
20+
```js
21+
rrweb.record({
22+
emit(event) {}, // 这是 rrweb 所必需的,但子页面不会发出任何事件
23+
recordCrossOriginIframes: true,
24+
});
25+
```
26+
27+
## 注意事项
28+
29+
当跨源 iframe 录制打开时,rrweb 将检查它是否正在顶级窗口中运行。
30+
如果不是,它将通过 `postMessage` 将事件发送到父窗口。
31+
32+
如果您没有在顶层窗口中运行 rrweb,则打开 `recordCrossOriginIframes` 时事件将丢失。
33+
34+
如果顶层窗口是一个恶意网站,它可以监听事件并将它们发送到它选择的服务器。
35+
36+
或者,如果您的页面上正在运行恶意脚本,他们可以监听“postMessage”,并且子窗口和父窗口之间的通信未加密。 他们可以看到事件。
37+
38+
## 将 rrweb 注入跨源 iframe 的选项
39+
40+
### 1. 网站所有者,在 iframe 中添加 rrweb
41+
42+
如果您拥有使用 iframe 的网站和嵌入在 iframe 中的网站,您可以通过脚本标签将 rrweb 添加到这两个页面。
43+
44+
### 2. 浏览器扩展
45+
46+
See https://developer.chrome.com/docs/extensions/mv3/content_scripts/#functionality
47+
48+
### 3. Puppeteer script
49+
50+
```js
51+
import puppeteer from 'puppeteer';
52+
53+
async function injectRecording(frame) {
54+
await frame.evaluate((rrwebCode) => {
55+
if (window.__IS_RECORDING__) return;
56+
window.__IS_RECORDING__ = true;
57+
58+
(async () => {
59+
function loadScript(code) {
60+
const s = document.createElement('script');
61+
s.type = 'text/javascript';
62+
s.innerHTML = code;
63+
if (document.head) {
64+
document.head.append(s);
65+
} else {
66+
requestAnimationFrame(() => {
67+
document.head.append(s);
68+
});
69+
}
70+
}
71+
loadScript(rrwebCode);
72+
73+
window.rrweb.record({
74+
emit: (event) => {
75+
window._captureEvent(event);
76+
},
77+
recordCrossOriginIframes: true,
78+
});
79+
})();
80+
}, code);
81+
}
82+
83+
const browser = await puppeteer.launch();
84+
const page = (await browser.pages())[0];
85+
86+
const events = []; // 包含来自所有帧的所有事件
87+
88+
await page.exposeFunction('_captureEvent', (event) => {
89+
events.push(event);
90+
});
91+
92+
page.on('framenavigated', async (frame) => {
93+
await injectRecording(frame); // 将 rrweb 注入 iframe
94+
});
95+
96+
await page.goto('https://example.com');
97+
98+
// 您的事件在事件数组中
99+
```
100+
101+
### 4. Electron
102+
103+
```ts
104+
const win = new BrowserWindow({
105+
width: 800,
106+
height: 600,
107+
webPreferences: {
108+
preload: path.join(__dirname, 'rrweb-recording-script.js'),
109+
// 这会打开 iframe 内的预加载,但会禁用节点集成
110+
nodeIntegrationInSubFrames: true,
111+
nodeIntegration: false,
112+
},
113+
});
114+
```
115+
116+
See https://www.electronjs.org/docs/latest/tutorial/tutorial-preload
117+
And https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts

0 commit comments

Comments
 (0)