[文件上传] 大文件切片上传前后端处理代码示例(JS / Node / Koa)
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}`
}
})