概述通过 Range 请求按偏移拉取资源,保存进度以支持中断恢复,并对数据进行校验以保障可靠性。断点续传与校验async function sha256(bytes) { const buf = await crypto.subtle.digest('SHA-256', bytes); return Array.from(new Uint8Array(buf)).map(x => x.toString(16).padStart(2,'0')).join(''); } async function downloadWithRange(url, chunkSize = 1024 * 1024) { let offset = await loadProgress(url); const parts = []; while (true) { const res = await fetch(url, { headers: { Range: `bytes=${offset}-${offset + chunkSize - 1}` } }); if (res.status === 416) break; if (!res.ok && res.status !== 206) throw new Error('range fetch failed'); const ab = await res.arrayBuffer(); const bytes = new Uint8Array(ab); parts.push(bytes); offset += bytes.length; await saveProgress(url, offset); if (bytes.length < chunkSize) break; } const total = parts.reduce((n, p) => n + p.length, 0); const out = new Uint8Array(total); let i = 0; for (const p of parts) { out.set(p, i); i += p.length; } const digest = await sha256(out); return { bytes: out, digest }; } 进度持久化示例function openDB(name) { return new Promise((resolve, reject) => { const r = indexedDB.open(name, 1); r.onupgradeneeded = () => { const db = r.result; if (!db.objectStoreNames.contains('progress')) db.createObjectStore('progress'); }; r.onsuccess = () => resolve(r.result); r.onerror = () => reject(r.error); }); } async function saveProgress(key, value) { const db = await openDB('range'); const tx = db.transaction('progress', 'readwrite'); tx.objectStore('progress').put(value, key); await new Promise((resolve, reject) => { tx.oncomplete = resolve; tx.onerror = () => reject(tx.error); }); db.close(); } async function loadProgress(key) { const db = await openDB('range'); const tx = db.transaction('progress', 'readonly'); const req = tx.objectStore('progress').get(key); const val = await new Promise((resolve, reject) => { req.onsuccess = () => resolve(req.result || 0); req.onerror = () => reject(req.error); }); db.close(); return val; }

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.644707s