大文件分片上传时断网导致分片丢失怎么处理?

极客志亮 阅读 41

在实现大文件上传时,用分片+断点续传的方法,但用户上传超过1GB视频时突然断网,发现有的分片丢失了,搞不懂哪里出错了。

尝试用resumable.js实现,设置分片大小5MB,但后端返回错误说”分片0已存在,但分片1丢失”。前端代码里用fetch发送分片时,用过catch捕获错误后重试,但重试时还是找不到丢失的分片序号。

这是分片上传的核心代码片段:


function uploadChunk(chunk) {
  const url = `/upload?fileId=${fileId}&chunk=${chunk.index}`;
  return fetch(url, {
    method: 'POST',
    body: chunk.data
  }).then(res => res.json());
}

试过设置重试次数但没用,断网后服务端好像没记录分片状态,有没有更好的状态同步方案?

我来解答 赞 5 收藏
二维码
手机扫码查看
2 条解答
Air-莹雪
我之前这样搞的,断网时分片状态不同步是因为前端重试时没先查服务器已上传的分片列表。每次上传前先发个HEAD请求拉一下已存在的分片索引,再补传缺失的。

async function uploadChunk(chunk) {
const res = await fetch(/upload?fileId=${fileId}&chunk=${chunk.index}, {
method: 'HEAD'
});
if (res.ok) return; // 分片已存在直接跳过
return fetch(/upload?fileId=${fileId}&chunk=${chunk.index}, {
method: 'POST',
body: chunk.data
}).then(res => res.json());
}
点赞 11
2026-02-09 06:13
统维
统维 Lv1
分片上传断网确实是个头疼的问题,主要是前后端状态同步没做好。给你个方案,前端每次上传前先询问服务端当前已有的分片,确保不遗漏。

前端改造成这样:

async function uploadFile(file, fileId) {
const chunkSize = 5 * 1024 * 1024; // 5MB
const chunks = Math.ceil(file.size / chunkSize);

// 先问服务端有哪些分片已经上传成功
const existingChunks = await getExistingChunks(fileId);

for (let i = 0; i < chunks; i++) {
if (existingChunks.includes(i)) {
console.log(分片${i}已存在,跳过);
continue;
}

const start = i * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunkData = file.slice(start, end);

let retry = 3;
while (retry > 0) {
try {
await uploadChunk(fileId, i, chunkData);
break;
} catch (e) {
console.error(分片${i}上传失败,重试中..., e);
retry--;
if (retry === 0) throw new Error(分片${i}多次重试失败);
}
}
}

// 最后通知服务端合并分片
await mergeChunks(fileId);
}

async function getExistingChunks(fileId) {
const res = await fetch(/status?fileId=${fileId});
return (await res.json()).chunks || [];
}

function uploadChunk(fileId, index, data) {
return fetch(/upload?fileId=${fileId}&chunk=${index}, {
method: 'POST',
body: data
}).then(res => res.json());
}

function mergeChunks(fileId) {
return fetch(/merge?fileId=${fileId}, { method: 'POST' });
}


后端需要实现三个接口:
1. /status 返回该文件已上传的分片列表
2. /upload 接收分片数据并保存
3. /merge 合并所有分片为完整文件

复制过去试试,记得调整chunkSize和重试次数。
点赞 3
2026-01-29 17:30