返回
React + Node 大文件分片上传、断点续传、秒传思路
前端
2024-01-06 20:27:40
随着互联网的发展,越来越多的数据需要在网上进行传输,其中就包括大文件。例如,视频、音频、图像和软件安装包等,这些文件动辄几十兆、上百兆,甚至上千兆。如果使用传统的上传方式,很容易造成网络拥塞,影响其他用户的正常使用。因此,我们需要一种新的方式来解决大文件上传的问题。
分片上传是一种常见的大文件上传技术。它的基本原理是将大文件切分成更小的块,然后将这些小块分别上传到服务器。服务器收到小块后,再将它们组装成完整的文件。这种方法可以有效地提高上传速度,并减少网络拥塞。
React 是一个流行的前端框架,它可以用来构建各种各样的 Web 应用。Node.js 是一个跨平台的 JavaScript 运行时环境,它可以用来构建各种各样的服务器端应用。本文将介绍如何使用 React + Node.js 实现大文件分片上传、断点续传和秒传。
React + Node 大文件分片上传、断点续传、秒传思路
整体思路
- 将文件切成多个小的文件;
- 将切片并行上传;
- 所有切片上传完成后,服务器端进行切片合成;
- 当分片上传失败,记录下失败的分片,下次继续上传失败的分片。
详细步骤
- 前端代码
首先,我们需要在前端代码中实现文件切片的功能。我们可以使用 FileReader
API 来读取文件,然后将文件分成更小的块。
const file = document.querySelector('input[type=file]');
file.addEventListener('change', (e) => {
const reader = new FileReader();
reader.onload = (e) => {
const arrayBuffer = e.target.result;
const chunkSize = 1024 * 1024; // 1MB
const chunks = [];
for (let i = 0; i < arrayBuffer.byteLength; i += chunkSize) {
const chunk = arrayBuffer.slice(i, i + chunkSize);
chunks.push(chunk);
}
// 上传切片
uploadChunks(chunks);
};
reader.readAsArrayBuffer(file.files[0]);
});
- Node.js 代码
在 Node.js 代码中,我们需要实现以下功能:
- 接收前端上传的切片;
- 将切片保存到本地磁盘;
- 当所有切片上传完成后,将切片合成完整的文件;
- 当分片上传失败,记录下失败的分片,下次继续上传失败的分片。
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const app = express();
// 使用 multer 处理文件上传
const upload = multer({ dest: 'uploads/' });
// 上传切片
app.post('/upload-chunk', upload.single('chunk'), (req, res) => {
const chunkNumber = req.body.chunkNumber;
const totalChunks = req.body.totalChunks;
const fileName = req.body.fileName;
// 将切片保存到本地磁盘
fs.writeFile(`uploads/${fileName}.part.${chunkNumber}`, req.file.buffer, (err) => {
if (err) {
res.status(500).json({ error: err });
return;
}
// 检查是否所有切片都已上传完成
if (chunkNumber === totalChunks) {
// 将切片合成完整的文件
const file = fs.createWriteStream(`uploads/${fileName}`);
for (let i = 0; i < totalChunks; i++) {
const chunk = fs.readFileSync(`uploads/${fileName}.part.${i}`);
file.write(chunk);
}
file.end();
// 删除临时切片文件
for (let i = 0; i < totalChunks; i++) {
fs.unlink(`uploads/${fileName}.part.${i}`, (err) => {
if (err) {
console.log(err);
}
});
}
res.status(200).json({ message: '文件上传成功' });
} else {
res.status(200).json({ message: '切片上传成功' });
}
});
});
// 断点续传
app.post('/resume-upload', upload.single('chunk'), (req, res) => {
const chunkNumber = req.body.chunkNumber;
const totalChunks = req.body.totalChunks;
const fileName = req.body.fileName;
// 检查切片是否已存在
fs.exists(`uploads/${fileName}.part.${chunkNumber}`, (exists) => {
if (exists) {
res.status(409).json({ error: '该切片已存在' });
return;
}
// 将切片保存到本地磁盘
fs.writeFile(`uploads/${fileName}.part.${chunkNumber}`, req.file.buffer, (err) => {
if (err) {
res.status(500).json({ error: err });
return;
}
res.status(200).json({ message: '切片上传成功' });
});
});
});
// 秒传
app.post('/check-file-exist', (req, res) => {
const fileName = req.body.fileName;
// 检查文件是否存在
fs.exists(`uploads/${fileName}`, (exists) => {
if (exists) {
res.status(200).json({ exists: true });
} else {
res.status(200).json({ exists: false });
}
});
});
app.listen(3000);
使用说明
- 首先,你需要在前端代码中实现文件切片的功能。
- 然后,你需要在 Node.js 代码中实现接收前端上传的切片、将切片保存到本地磁盘、当所有切片上传完成后,将切片合成完整的文件、当分片上传失败,记录下失败的分片,下次继续上传失败的分片的功能。
- 最后,你就可以使用 React + Node.js 来实现大文件分片上传、断点续传和秒传的功能了。