You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js使用Multer同时上传图片视频时Postman报Unexpected field错误

问题原因和修复方案

错误根因

  • multer的diskStorage配置参数不存在filename1、filename2属性,官方标准属性名为filename,自定义的属性名不会被multer识别,导致文件名生成逻辑失效
  • 不能在同一个路由上同时挂载两个multer单文件上传中间件:第一个multer中间件会消费完请求的formData数据流,第二个中间件无法再读取到对应字段的文件,自然抛出Unexpected field错误
  • multer的single()方法只会将单个文件挂载到req.file上,同时上传两个不同字段的文件时需要用fields()方法,文件会挂载到复数形式的req.files上,原有控制器里读取req.file.filename1、req.file.filename2的写法不成立
  • 视频MIME类型配置里多写了一个斜杠,video//webm要改成video/webm

具体修复步骤

步骤1:合并multer配置,创建新的多文件上传中间件

新建middlewares/multer-upload.js,代码如下:

const multer = require('multer');

// 合并所有支持的MIME类型
const MIME_TYPES = {
  // 图片类型
  'image/jpg': 'jpg',
  'image/jpeg': 'jpg',
  'image/png': 'png',
  // 视频类型
  'video/mp4': 'mp4',
  'video/mpeg': 'mpeg',
  'video/ogg': 'ogv',
  'video/mp2t': 'ts',
  'video/webm': 'webm'
}

const storage = multer.diskStorage({
  // 根据文件类型判断存储路径
  destination: (req, file, callback) => {
    let uploadPath = 'public/images/exercise';
    if (file.mimetype.startsWith('video/')) {
      uploadPath = 'public/videos/exercise';
    }
    callback(null, uploadPath);
  },
  // 统一使用官方标准的filename属性生成文件名
  filename: (req, file, callback) => {
    let name = Math.floor(Math.random() * Math.floor(123456789)).toString();
    name += Math.floor(Math.random() * Math.floor(123456789)).toString();
    name += Math.floor(Math.random() * Math.floor(123456789)).toString();
    name += Math.floor(Math.random() * Math.floor(123456789)).toString();
    name += Date.now() + ".";
    const extension = MIME_TYPES[file.mimetype];
    name += extension;
    callback(null, name)
  }
})

// 配置同时接收image和video两个字段的单文件,对应Postman里的字段名
module.exports = multer({ storage }).fields([
  { name: 'image', maxCount: 1 },
  { name: 'video', maxCount: 1 }
]);

步骤2:修改路由配置

删除原来引入的两个独立multer中间件,替换为新的多文件上传中间件:

var express = require('express');
var router = express.Router();
var exerciseController = require('../controllers/exerciseController');
// 引入合并后的多文件上传中间件
const multerUpload = require('../middlewares/multer-upload');

/* GET home page. */
router.get('/show', exerciseController.show);
// 只挂载一个multer中间件即可
router.post('/create', multerUpload, exerciseController.create);
// 如果update接口也要同时传视频,也可以替换为multerUpload,根据自己的业务调整
router.put('/update/:id', multerUpload, exerciseController.update);

module.exports = router;

步骤3:修改控制器里的文件读取逻辑

multer的fields()方法会将文件挂载到req.files对象上,每个字段对应的值是文件数组,取第一个元素的filename即可:

create:(req,res)=>{
  console.log("Test1");
  console.log("Test1bis");
  console.log("Test2")
  var exerciseB = new Exercise({
    ...req.body,
    // 从req.files中读取对应字段的文件名
    image: `${req.protocol}://${req.get('host')}/images/exercise/${req.files.image[0].filename}`,
    video: `${req.protocol}://${req.get('host')}/videos/exercise/${req.files.video[0].filename}`
  })
  console.log("Test3")

  exerciseB.save((err,exercise)=>{
    if(err){
      console.log("C'est le 2eme err");
      return res.status(500).json({
        status:500,
        message:err.message
      })
    }
    console.log("Ca arrive jusqu'au 200");
    return res.status(201).json({
      status:200,
      message:"Exercise Created Successfully !"
    })
  })
}

内容的提问来源于stack exchange,提问作者user17205196

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:36:03