实现了哪些功能
- 前端使用 Blob.slice 将大文件切成多个 1MB 分片。
- 上传前计算文件 SHA-256,生成稳定的 uploadId。
- 通过 /api/status 查询服务端已有分片,实现断点续传。
- 通过 /api/upload-chunk 并发上传缺失分片。
- 通过 /api/merge 通知服务端按顺序合并文件并校验 hash。
- 页面支持暂停、继续、失败重试、进度展示和运行日志。
选择文件后,前端按固定大小切片上传。刷新页面或中断后再次选择同一个文件,会先查询服务端已有分片,只补传缺失部分,最后由 Python 服务端合并并校验 SHA-256。
分片大小:1MB,并发数:3,支持暂停、继续、重试和断点续传。
核心是切片、查询已有分片、只上传缺失分片。
const chunks = [];
for (let start = 0; start < file.size; start += CHUNK_SIZE) {
chunks.push(file.slice(start, start + CHUNK_SIZE));
}
const status = await fetch(`/api/status?uploadId=${uploadId}`);
const uploaded = new Set((await status.json()).uploadedChunks);
const pending = chunks
.map((chunk, index) => ({ chunk, index }))
.filter((item) => !uploaded.has(item.index));
服务端把每个分片保存到 uploads/chunks/{uploadId}/{index},合并时按 index 顺序写入最终文件。
with chunk_path.open('wb') as file:
remaining = content_length
while remaining > 0:
data = self.rfile.read(min(1024 * 1024, remaining))
file.write(data)
remaining -= len(data)
with target_path.open('wb') as target:
for index in range(total_chunks):
with (upload_dir / str(index)).open('rb') as chunk:
shutil.copyfileobj(chunk, target)