react实现断点续传
断点续传的实现原理
断点续传的核心在于将大文件分割为多个小块,上传时记录已上传的部分。当网络中断或暂停后重新上传时,只需上传未完成的部分,减少重复传输。
前端实现步骤
使用React实现断点续传需要结合文件分片、MD5校验和进度记录等技术:

文件分片处理
通过File对象的slice方法将文件切割为固定大小的块(如1MB)。使用spark-md5库计算文件唯一hash,作为断点标识:
const chunkSize = 1024 * 1024; // 1MB
const chunks = Math.ceil(file.size / chunkSize);
const spark = new SparkMD5.ArrayBuffer();
for (let i = 0; i < chunks; i++) {
const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
spark.append(chunk);
}
const fileHash = spark.end();
上传状态管理
使用React的useState记录上传进度和已完成的块:

const [uploadedChunks, setUploadedChunks] = useState([]);
const [progress, setProgress] = useState(0);
分片上传控制
通过FormData发送每个分片,服务端需支持分片合并:
const uploadChunk = async (chunk, chunkIndex) => {
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('chunkIndex', chunkIndex);
formData.append('fileHash', fileHash);
await axios.post('/upload', formData, {
onUploadProgress: (e) => {
const percent = Math.round((e.loaded / e.total) * 100);
setProgress(prev => prev + percent/chunks);
}
});
setUploadedChunks(prev => [...prev, chunkIndex]);
};
服务端配合要点
- 分片存储:临时存储接收的分片,通常按文件hash建立目录
- 合并接口:当所有分片上传完成后触发合并操作
- 校验接口:上传前检查哪些分片已存在
Node.js示例代码:
app.post('/merge', async (req, res) => {
const { fileHash, fileName } = req.body;
const chunkDir = path.resolve('temp', fileHash);
const chunks = await fs.readdir(chunkDir);
chunks.sort((a, b) => a - b).forEach(chunk => {
fs.appendFileSync(
path.resolve('uploads', fileName),
fs.readFileSync(path.resolve(chunkDir, chunk))
);
fs.unlinkSync(path.resolve(chunkDir, chunk));
});
fs.rmdirSync(chunkDir);
});
优化建议
- 使用Web Worker计算文件hash避免界面卡顿
- 实现并发上传控制(如最多5个并行请求)
- 添加暂停/恢复功能时清除未完成的axios请求
- 本地缓存已上传分片信息(使用localStorage)
完整流程示例
- 用户选择文件后计算文件hash
- 向服务端查询已上传的分片列表
- 只上传缺失的分片
- 全部分片上传完成后请求合并
- 显示最终上传结果
通过这种方式可以实现稳定可靠的断点续传功能,适合大文件上传场景。






