Multer中file.size未定义求助:多文件上传无法获取单个文件大小
问题:Multer filename中间件中无法获取单个文件的file.size?
我使用Multer处理多文件上传,在filename中间件中编写了如下代码:
filename: async (req, file, cb) => { console.log(Object.keys(file)); ({ rows } = await db.query(` INSERT INTO public.files( uuid, nom, type, size ) VALUES ($1, $2, $3, $4) RETURNING *`, [ req.uuid, file.originalname, file.mimetype, file.size, // +req.headers["content-length"], ])); cb(null, uuid); },
问题在于file.size始终为undefined,我已确认发送文件前文件大小是存在的。通过console.log查看file对象的属性,仅包含'fieldname', 'originalname', 'encoding', 'mimetype'。若使用+req.headers["content-length"],获取的是整个请求的总大小而非单个文件的大小。请问为何无法获取单个文件大小?是无法实现还是存在未找到的配置项?
解决办法
核心原因是:Multer的filename钩子是在文件开始写入前触发的,此时文件还未被完全接收,file.size字段还未被计算填充,所以你在这个阶段拿不到单个文件的大小。
有两种可行的解决方式:
1. 挪到文件上传完成后处理数据库插入
在Multer处理完文件上传的路由回调里,req.files(多文件)或req.file(单文件)中的每个文件对象都会包含完整的size属性,此时再遍历文件执行数据库插入即可:
// 假设你用upload.array('files')处理多文件上传 app.post('/upload', upload.array('files'), async (req, res) => { try { for (const file of req.files) { await db.query(` INSERT INTO public.files( uuid, nom, type, size ) VALUES ($1, $2, $3, $4) RETURNING *`, [ req.uuid, file.originalname, file.mimetype, file.size, ]); } res.status(200).json({ message: '文件上传并入库成功' }); } catch (err) { res.status(500).json({ error: err.message }); } });
2. 先入库再更新文件大小(适合必须在filename阶段关联记录的场景)
如果业务上需要在filename阶段就生成关联的数据库记录,可以先插入一条size为null或默认值的记录,等文件上传完成后再通过唯一标识(比如你用的req.uuid)更新这条记录的size:
// filename钩子中先插入无size的记录 filename: async (req, file, cb) => { await db.query(` INSERT INTO public.files( uuid, nom, type, size ) VALUES ($1, $2, $3, $4) RETURNING *`, [ req.uuid, file.originalname, file.mimetype, null // 先设为null ]); cb(null, req.uuid); // 用uuid作为文件名,方便后续关联 }, // 路由回调中更新size app.post('/upload', upload.array('files'), async (req, res) => { try { for (const file of req.files) { await db.query(` UPDATE public.files SET size = $1 WHERE uuid = $2`, [ file.size, file.filename // 因为filename设为了uuid,直接拿这个关联 ]); } res.status(200).json({ message: '文件上传并更新成功' }); } catch (err) { res.status(500).json({ error: err.message }); } });
需要注意的是,Multer的版本差异可能带来细节变化,但核心逻辑一致:filename是前置钩子,仅负责生成文件名,此时文件还未完成传输,无法获取准确的单个文件大小。
内容的提问来源于stack exchange,提问作者djcaesar9114
相关产品推荐
相关产品推荐

