[文件上传] 大文件切片上传前后端处理代码示例(JS / Node / Koa)

时间:2025-01-28 08:27:16
const storage = multer.diskStorage({ // -- 1. 自定义存储引擎(文件存储路径等) destination: function (req, file, cb) { cb(null, resolve(__dirname, './static/temp/')) // -- 保存的路径 }, filename: function (req, file, cb) { cb(null, file.originalname); // -- 使用 file 中原来的名字 → 方便合并操作等 } }); const upload = multer({ storage: storage }); // 初始化 upload 对象 // -- 2. 分片文件上传接口 → 使用上面 upload 对象中的中间件,自动根据上面存储引擎中的存储路径将对应上传的 FormData 文件数据进行生成对应文件进行存储(临时文件,后续合并后会删除) router.post("/upload", upload.single('file'), async (ctx) => { ctx.body = { message: "uploaded success~" } }) // -- 3. merge 合并文件分片数据接口 const TEMP_DIR = resolve(__dirname, "./static/temp") // -- 定义临时文件路径 → 方便后续使用 const UPLOAD_DIR = resolve(__dirname, "./static/uploads") // -- 定义合并后文件路径 → 方便后续使用 router.post("/merge", async (ctx) => { // -- 接口实现 // -- 获取请求中的文件名于对应后缀名 → 根据该文件名查找对应分片文件 : 根据后缀名创建对应类型的合并文件 const { filename, fileExtension } = ctx.request.body // -- 在 UPLOAD_DIR 中创建对应的合并文件,该路径用于方便后续写入切片数据时,获取写入文件路径 const NEW_FILE_PATH = UPLOAD_DIR + `/${filename}.${fileExtension}` fse.createFileSync(NEW_FILE_PATH) // -- 在 uploads 中创建对应的数据写入文件 // -- 查看 temp 目录下的所有临时文件 → 用于里面查找对应切片文件,并进行数据的写入(↑) fse.readdir(TEMP_DIR, (err, files) => { // -- 过滤出需要合并的临时文件的文件名 const mergeFilename = files.filter(item => item.includes(filename)) // -- 遍历所有分片文件 → 将每一部分切片文件的数据写入至对应的文件中 mergeFilename.sort().forEach(filename => { // -- 读取对应分片文件中的数据 const buffer = fse.readFileSync(TEMP_DIR + "/" + filename) try { // -- 写入切片文件数据至 uploads 中对应的合并文件中 fse.appendFileSync(NEW_FILE_PATH, buffer) // -- 数据写入后,删除对应历史文件 fse.unlinkSync(TEMP_DIR + "/" + filename) } catch (error) { ctx.body = { // -- 写入失败响应 message: "Error", error } console.log("err:", error); } }) }) ctx.body = { // -- 写入成功响应 message: "OK", // -- 返回对应文件访问路径 → 注意访问静态资源不需要加上配置的静态目录(即路径上不需要加上 static) url: "http://localhost:3000/uploads" + `/${filename}.${fileExtension}` } })