lsc 3 hari lalu
induk
melakukan
5ee365329c
1 mengubah file dengan 53 tambahan dan 26 penghapusan
  1. 53 26
      src/views/Student/index.vue

+ 53 - 26
src/views/Student/index.vue

@@ -1101,54 +1101,81 @@ const handleHomeworkSubmit = async () => {
           // 尝试使用html2canvas,对iframe支持更好
           let imageData: string
           const screenSlides = document.querySelectorAll('.viewer-canvas .screen-slide')
-          let iframe: HTMLElement | null = null
+          let iframeElement: HTMLIFrameElement | null = null
+
+          // 直接获取iframe元素本身,而不是其内部文档
           if (
             screenSlides &&
             screenSlides[slideIndex.value] &&
-            screenSlides[slideIndex.value].querySelector('iframe') &&
-            (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow &&
-            (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow!.document &&
-            (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow!.document.body
+            screenSlides[slideIndex.value].querySelector('iframe')
           ) {
-            iframe = (screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement).contentWindow!.document.body as HTMLElement
+            iframeElement = screenSlides[slideIndex.value].querySelector('iframe') as HTMLIFrameElement
           }
           else {
-            throw new Error('未能获取到iframe的body元素,无法截图')
+            throw new Error('未能获取到iframe元素,无法截图')
           }
+
           try {
-            const a = iframe.getElementsByTagName('img')
-            for (let i = 0;i < a.length;i++) {
-              a[i].crossOrigin = 'anonymous'
-            }
-            // 首先尝试使用html2canvas
+            // 直接对iframe元素进行截图,而不是其内部文档
             const html2canvas = await import('html2canvas')
-            const canvas = await html2canvas.default(iframe, {
+            const canvas = await html2canvas.default(iframeElement, {
               useCORS: true,
               allowTaint: true,
               scale: 1,
               backgroundColor: '#ffffff',
               logging: false,
-              // 尝试截取iframe内容
+              // 对iframe元素进行截图
               foreignObjectRendering: true,
-              removeContainer: true
+              removeContainer: true,
+              // 添加iframe特定的配置
+              ignoreElements: (element) => {
+                // 忽略可能引起问题的元素
+                return element.tagName === 'SCRIPT' || element.tagName === 'STYLE'
+              }
             })
             imageData = canvas.toDataURL('image/png', 0.95)
-            const _a = iframe.getElementsByTagName('img')
-            for (let i = 0; i < _a.length; i++) {
-              _a[i].removeAttribute('crossorigin')
-            }
             console.log('使用html2canvas截图成功')
           }
           catch (html2canvasError) {
             console.log('html2canvas截图失败,回退到html-to-image:', html2canvasError)
             
-            // 回退到html-to-image
-            const { toPng } = await import('html-to-image')
-            imageData = await toPng(iframe, {
-              quality: 0.95,
-              backgroundColor: '#ffffff'
-            })
-            console.log('使用html-to-image截图成功')
+            try {
+              // 回退到html-to-image
+              const { toPng } = await import('html-to-image')
+              imageData = await toPng(iframeElement, {
+                quality: 0.95,
+                backgroundColor: '#ffffff'
+              })
+              console.log('使用html-to-image截图成功')
+            }
+            catch (htmlToImageError) {
+              console.log('html-to-image也失败了,尝试备用方案:', htmlToImageError)
+              
+              // 最后的备用方案:使用canvas直接绘制iframe
+              const canvas = document.createElement('canvas')
+              const ctx = canvas.getContext('2d')
+              if (ctx) {
+                canvas.width = iframeElement.offsetWidth
+                canvas.height = iframeElement.offsetHeight
+                
+                // 绘制iframe的可见区域
+                ctx.fillStyle = '#ffffff'
+                ctx.fillRect(0, 0, canvas.width, canvas.height)
+                
+                // 添加一个提示文本
+                ctx.fillStyle = '#666666'
+                ctx.font = '16px Arial'
+                ctx.textAlign = 'center'
+                ctx.fillText('无法截图iframe内容', canvas.width / 2, canvas.height / 2)
+                ctx.fillText('(跨域限制)', canvas.width / 2, canvas.height / 2 + 20)
+                
+                imageData = canvas.toDataURL('image/png', 0.95)
+                console.log('使用备用方案截图成功')
+              }
+              else {
+                throw new Error('无法创建canvas上下文')
+              }
+            }
           }
           
           // 将base64字符串转换为File对象