返回 AiToEarn
download.ts
根目录 / project / aitoearn-web / src / utils / download.ts
1 /**
2 * download.ts - 下载工具函数
3 * 提供带进度回调的文件下载功能
4 */
5
6 /**
7 * 带进度回调的 fetch 下载
8 * 通过 ReadableStream 读取响应体,实时计算下载百分比
9 * 无 Content-Length 时降级为无进度下载(直接 blob)
10 */
11 export async function fetchWithProgress(
12 url: string,
13 onProgress?: (progress: number) => void,
14 init?: RequestInit,
15 ): Promise<Blob> {
16 const response = await fetch(url, init ?? { mode: 'no-cors' })
17 if (!response.ok) {
18 throw new Error(`Download failed: ${response.status}`)
19 }
20
21 const contentLength = response.headers.get('Content-Length')
22 // 无 Content-Length 或无 body,降级为直接 blob
23 if (!contentLength || !response.body) {
24 const blob = await response.blob()
25 onProgress?.(100)
26 return blob
27 }
28
29 const total = Number.parseInt(contentLength, 10)
30 let loaded = 0
31 const reader = response.body.getReader()
32 const chunks: Uint8Array[] = []
33
34 while (true) {
35 const { done, value } = await reader.read()
36 if (done)
37 break
38 chunks.push(value)
39 loaded += value.length
40 onProgress?.(Math.round((loaded / total) * 100))
41 }
42
43 return new Blob(chunks as BlobPart[])
44 }
45
45 lines TYPESCRIPT