@@ -20,9 +20,42 @@ function getCode() {
2020void  ( async  ( )  =>  { 
2121  const  code  =  getCode ( ) ; 
2222  let  events  =  [ ] ; 
23+   let  injectionInProgress  =  false ; 
2324
2425  async  function  injectRecording ( frame )  { 
26+     // 防止并发注入 
27+     if  ( injectionInProgress )  { 
28+       return ; 
29+     } 
30+ 
2531    try  { 
32+       injectionInProgress  =  true ; 
33+ 
34+       // 检查 frame 是否仍然有效 
35+       if  ( frame . isDetached ( ) )  { 
36+         console . log ( 'Frame is detached, skipping injection' ) ; 
37+         return ; 
38+       } 
39+ 
40+       // 等待页面稳定 
41+       await  new  Promise ( resolve  =>  setTimeout ( resolve ,  1000 ) ) ; 
42+ 
43+       // 再次检查 frame 状态 
44+       if  ( frame . isDetached ( ) )  { 
45+         console . log ( 'Frame became detached while waiting, skipping injection' ) ; 
46+         return ; 
47+       } 
48+ 
49+       // 检查是否已经注入过 
50+       const  alreadyInjected  =  await  frame . evaluate ( ( )  =>  { 
51+         return  window . __IS_RECORDING__  ===  true ; 
52+       } ) . catch ( ( )  =>  false ) ; 
53+ 
54+       if  ( alreadyInjected )  { 
55+         console . log ( 'Recording script already injected' ) ; 
56+         return ; 
57+       } 
58+ 
2659      await  frame . evaluate ( ( rrwebCode )  =>  { 
2760        const  win  =  window ; 
2861        if  ( win . __IS_RECORDING__ )  return ; 
@@ -38,27 +71,45 @@ void (async () => {
3871              document . head . append ( s ) ; 
3972            }  else  { 
4073              requestAnimationFrame ( ( )  =>  { 
41-                 document . head . append ( s ) ; 
74+                 if  ( document . head )  { 
75+                   document . head . append ( s ) ; 
76+                 } 
4277              } ) ; 
4378            } 
4479          } 
4580          loadScript ( rrwebCode ) ; 
4681
4782          win . events  =  [ ] ; 
48-           rrweb . record ( { 
49-             emit : ( event )  =>  { 
50-               win . events . push ( event ) ; 
51-               win . _replLog ( event ) ; 
52-             } , 
53-             plugins : [ ] , 
54-             recordCanvas : true , 
55-             recordCrossOriginIframes : true , 
56-             collectFonts : true , 
57-           } ) ; 
83+           // 添加全局错误处理 
84+           try  { 
85+             rrweb . record ( { 
86+               emit : ( event )  =>  { 
87+                 win . events . push ( event ) ; 
88+                 if  ( win . _replLog )  { 
89+                   win . _replLog ( event ) ; 
90+                 } 
91+               } , 
92+               plugins : [ ] , 
93+               recordCanvas : true , 
94+               recordCrossOriginIframes : true , 
95+               collectFonts : true , 
96+             } ) ; 
97+             console . log ( 'rrweb recording started successfully' ) ; 
98+           }  catch  ( e )  { 
99+             console . error ( 'Failed to start rrweb recording:' ,  e ) ; 
100+           } 
58101        } ) ( ) ; 
59102      } ,  code ) ; 
103+ 
104+       console . log ( 'Recording script injected successfully' ) ; 
60105    }  catch  ( e )  { 
61-       console . error ( 'failed to inject recording script:' ,  e ) ; 
106+       // 只在非上下文销毁错误时输出错误信息 
107+       if  ( ! e . message . includes ( 'Execution context was destroyed' )  && 
108+           ! e . message . includes ( 'detached frame' ) )  { 
109+         console . error ( 'Failed to inject recording script:' ,  e . message ) ; 
110+       } 
111+     }  finally  { 
112+       injectionInProgress  =  false ; 
62113    } 
63114  } 
64115
@@ -153,6 +204,8 @@ void (async () => {
153204        '--start-maximized' , 
154205        '--ignore-certificate-errors' , 
155206        '--no-sandbox' , 
207+         '--disable-web-security' , 
208+         '--disable-features=VizDisplayCompositor' 
156209      ] , 
157210    } ) ; 
158211    const  page  =  await  browser . newPage ( ) ; 
@@ -161,15 +214,36 @@ void (async () => {
161214      events . push ( event ) ; 
162215    } ) ; 
163216
164-     page . on ( 'framenavigated' ,  async  ( frame )  =>  { 
165-       await  injectRecording ( frame ) ; 
166-     } ) ; 
217+     // 使用去抖动的注入函数 
218+     let  injectionTimeout ; 
219+     const  debouncedInject  =  ( frame )  =>  { 
220+       clearTimeout ( injectionTimeout ) ; 
221+       injectionTimeout  =  setTimeout ( ( )  =>  { 
222+         injectRecording ( frame ) ; 
223+       } ,  500 ) ; 
224+     } ; 
225+ 
226+     page . on ( 'framenavigated' ,  debouncedInject ) ; 
167227
168-     await  page . goto ( url ,  { 
169-       waitUntil : 'domcontentloaded' , 
170-       timeout : 300000 , 
228+     // 监听页面加载完成事件 
229+     page . on ( 'load' ,  ( )  =>  { 
230+       setTimeout ( ( )  =>  { 
231+         injectRecording ( page . mainFrame ( ) ) ; 
232+       } ,  1000 ) ; 
171233    } ) ; 
172234
235+     try  { 
236+       await  page . goto ( url ,  { 
237+         waitUntil : 'domcontentloaded' , 
238+         timeout : 300000 , 
239+       } ) ; 
240+ 
241+       // 初始注入 
242+       await  injectRecording ( page . mainFrame ( ) ) ; 
243+     }  catch  ( e )  { 
244+       console . error ( 'Failed to navigate to URL:' ,  e . message ) ; 
245+     } 
246+ 
173247    emitter . once ( 'done' ,  async  ( shouldReplay )  =>  { 
174248      const  pages  =  await  browser . pages ( ) ; 
175249      await  Promise . all ( pages . map ( ( page )  =>  page . close ( ) ) ) ; 
0 commit comments