Browse Source

feat(导入功能): 添加 getFile2 方法作为文件获取的备用方案

新增 getFile2 方法使用 fetch API 直接获取文件内容,作为 getFile 方法的备用方案。在 Student 视图中的 processIframeLinks 方法中,当 getFile 失败时会尝试使用 getFile2,最后才回退到 getHTML 方法,提高文件获取的可靠性。
lsc 1 day ago
parent
commit
587f341fe2
2 changed files with 47 additions and 10 deletions
  1. 28 2
      src/hooks/useImport.ts
  2. 19 8
      src/views/Student/index.vue

+ 28 - 2
src/hooks/useImport.ts

@@ -936,7 +936,6 @@ export default () => {
       const params = {
         Bucket: 'ccrb',
         Key: name,
-        ResponseContentEncoding: 'url' // 禁止对特殊字符的编码处理
       }
       
       s3.getObject(params, (err: any, data: any) => {
@@ -952,6 +951,32 @@ export default () => {
     })
   }
 
+    
+  const getFile2 = (url: string): Promise<{ data: any }> => {
+    return new Promise((resolve, reject) => {
+      console.log('直接使用原始 URL 获取文件:', url)
+      
+      // 直接使用 fetch 获取文件,浏览器会自动处理 URL 解码
+      fetch(url)
+        .then(response => {
+          if (!response.ok) {
+            console.error('HTTP 错误:', response.status, response.statusText)
+            throw new Error(`HTTP error! status: ${response.status}`)
+          }
+          console.log('文件获取成功,大小:', response.headers.get('content-length'))
+          return response.arrayBuffer()
+        })
+        .then(buffer => {
+          console.log('文件内容读取成功,大小:', buffer.byteLength)
+          resolve({ data: buffer })
+        })
+        .catch(error => {
+          console.error('Fetch error:', error)
+          reject(error)
+        })
+    })
+  }
+
   return {
     importSpecificFile,
     importJSON,
@@ -959,6 +984,7 @@ export default () => {
     readJSON,
     exportJSON2,
     exporting,
-    getFile
+    getFile,
+    getFile2
   }
 }

+ 19 - 8
src/views/Student/index.vue

@@ -1253,7 +1253,7 @@ const clearAllSyncStates = () => {
 }
 
 // 获取导入导出功能
-const { readJSON, exportJSON2, getFile } = useImport()
+const { readJSON, exportJSON2, getFile, getFile2 } = useImport()
 
 // 根据iframe的URL查找对应的幻灯片索引
 const findSlideIndexByIframeUrl = (iframeUrl: string): number => {
@@ -1507,15 +1507,26 @@ const processIframeLinks = async () => {
                     }
                   }
                   catch (error) {
-                    console.log(`getFile 失败,尝试使用 getHTML:`, error)
+                    console.log(`getFile 失败,尝试使用 getFile2:`, error)
                     try {
-                      html = await api.getHTML(iframeSrc)
-                      console.log('getHTML 成功获取内容:', html)
+                      const fileData2 = await getFile2(iframeSrc)
+                      if (fileData2 && fileData2.data) {
+                        const uint8Array = new Uint8Array(fileData2.data)
+                        html = new TextDecoder('utf-8').decode(uint8Array)
+                        console.log('getFile2 成功获取内容:', html)
+                      }
                     }
-                    catch (htmlError) {
-                      console.error('getHTML 也失败:', htmlError)
-                      console.error('无法获取内容: getFile 和 getHTML 都失败了')
-                      // throw new Error(`无法获取内容: getFile 和 getHTML 都失败了`)
+                    catch (error2) {
+                      console.log(`getFile2 失败,尝试使用 getHTML:`, error2)
+                      try {
+                        html = await api.getHTML(iframeSrc)
+                        console.log('getHTML 成功获取内容:', html)
+                      }
+                      catch (htmlError) {
+                        console.error('getHTML 也失败:', htmlError)
+                        console.error('无法获取内容: getFile、getFile2 和 getHTML 都失败了')
+                        // throw new Error(`无法获取内容: getFile、getFile2 和 getHTML 都失败了`)
+                      }
                     }
                   }
                   console.log(`处理幻灯片 ${slideIndex + 1} 中的iframe链接:`, iframeSrc)