Multer多文件上传(fields/any模式)下如何正确获取req.files文件数据?
Multer多文件模式下的文件数据获取正确方法
所有之前的取值失效问题,本质都是没对齐不同Multer多文件方法返回的req.files数据结构,和Multer作为中间件的特性本身没有关系,只要结构对、语法对,取值逻辑和单文件模式完全一致。
分模式对应取值规则
Multer提供的多文件上传方法不是统一返回同一种结构,两种常用模式的结构和取值逻辑完全不同:
1. 使用multer_upload.fields([...])配置固定上传字段的场景
这个模式下的req.files不是数组,是以允许的上传字段名为键的普通对象,每个键对应的 value 是当前字段名下传上来的文件组成的数组:
- 之前写的
req.files[0]、req.files.find(...)的写法必然失效,因为对象本身就没有0下标这个键,也没有find方法 - 按字段名取文件的正确写法:直接把字段名作为对象的键访问,后续加文件下标的数组操作即可
对照示例:
// 提前定义允许的上传字段 const upload = multer({ dest: 'uploads/' }) const fixedFieldUpload = upload.fields([ { name: 'user_avatar', maxCount: 1 }, { name: 'work_attach', maxCount: 5 } ]) // 路由处理(中间件必须挂在处理函数之前) app.post('/user/submit', fixedFieldUpload, (req, res) => { // 直接按键名取,拿到的是当前字段下的文件数组 const avatarFileArr = req.files['user_avatar'] const attachFileArr = req.files['work_attach'] // 取文件名的逻辑和单文件一致 const avatarName = avatarFileArr[0].filename const firstAttachName = attachFileArr[0].filename })
2. 使用multer_upload.any()接收任意字段上传的场景
这个模式下的req.files是标准的文件对象数组,每个数组元素的结构和单文件模式下的req.file完全一致,自带fieldname、filename、mimetype等属性:
- 这种模式下
req.files[0].filename的写法本身是完全成立的,取不到值一般是数组为空(没有上传文件、中间件没挂对、formdata格式不对) - 之前写的
req.files.find({fieldname:"sample_fieldname"})失效,是因为JS原生数组的find方法不支持传入MongoDB风格的查询条件对象,必须传入一个返回布尔值的判断函数 - 正确的按字段名筛选写法:
对照示例:
// any模式中间件 const anyUpload = upload.any() app.post('/upload/any', anyUpload, (req, res) => { // 按下标取,只要数组有值就正常 const firstFile = req.files[0] const firstFileName = firstFile.filename // 按字段名正确筛选 const targetFile = req.files.find(item => item.fieldname === 'sample_fieldname') if (targetFile) { const targetFileName = targetFile.filename } })
常见取值失效排查清单
- 检查路由的中间件挂载顺序:必须把Multer中间件放在路由业务处理函数之前,否则
req.files根本不会被解析填充,全程都是undefined - 不要混淆两种多文件模式的结构:把fields模式的对象当成数组用、把any模式的数组当成对象按键取,都会报undefined
- 核对前端FormData的字段名:必须和Multer配置的字段名完全一致(区分大小写),否则对应字段下的文件不会被解析
- 注意原生数组方法的语法:JS数组的
find、filter等方法不支持传查询条件对象,必须写箭头函数做条件判断
内容的提问来源于stack exchange,提问作者joashe
相关产品推荐
相关产品推荐

