Busboy是一个非常的Node.js库,用于处理multipart/form-data格式的文件上传,常用于Express.js等框架中的文件上传功能。它通过流(Stream)处理上传的文件,因此能够处理大文件。
前端使用的是Ant Design中的 Upload 组件 后端使用的是Node.js以及第三方库Busboy 代码实现如下:
<Upload
key="dbbackup"
name="dbbackup"
accept={[".tgz",".txt"]}
action="api/file/upload?type=dbbackup"
multiple
onChange={rs => {
setUploading(["uploading"].includes(rs?.file?.status));
if (rs?.file?.status === "error") {
message.error(gLabelList.upload_failed);
return;
}
if (rs?.file?.status === "done") {
message.error(gLabelList.upload_sucess);
}
}}
>
<Button type="primary">上传</Button>
</Upload>
后端代码实现:
const fs = require("fs");
const busboy = require("busboy");
const express = require("express");
const router = express.Router();
const uploadPath = path.join(process.cwd(), "upload");
const dbbackupPath = path.join(process.cwd(), "dbbackup");
router.post("/upload", (req, res) => {
try {
// 从请求的查询字符串(req.query)中提取type参数,type用于决定文件的处理方式或保存位置。
const {type} = req.query;
const bb = busboy({headers: req.headers});
let fileName;
// 注册file事件监听器,用于处理上传的文件。当有文件上传时,name是字段名(文件上传时的字段字段名称),file是文件流,info包含文件的相关信息(如文件名、文件类型等)
bb.on("file", (name, file, info) => {
// 将上传的文件名(info.filename)从二进制转换为UTF-8编码的字符串,以确保文件名正确处理(特别是在不同编码的情况下)。
fileName = info.filename = Buffer.from(info.filename, "binary").toString("utf8");
// 根据type的值来决定文件保存的路径:
// 如果type为"dbbackup",文件将被保存到dbbackupPath目录中。
// 如果type为其他值,文件将被保存到uploadPath/type目录下。
// file.pipe()将文件流写入到指定路径的文件中。
type === "dbbackup"
? file.pipe(fs.createWriteStream(path.join(dbbackupPath, fileName)))
: file.pipe(fs.createWriteStream(path.join(uploadPath, type, fileName)));
}).on("close", async () => {
// 注册close事件监听器,该事件在文件处理完成后触发,表示文件上传已完成。
const fileList = type === "dbbackup"
? fs.readdirSync(path.join(dbbackupPath)).map(name => ({uid: name, name}))
: fs.readdirSync(path.join(uploadPath, type)).map(name => ({uid: name, name}));
res.json({apiResult: "complete", fileList});
});
return req.pipe(bb);
} catch (e) {
res.json({apiResult: "fail", apiMessage: e});
}
});
module.exports = router