You need to enable JavaScript to run this app. React使用express-fileupload时如何获取其他表单文本输入字段
优惠活动
大模型
产品
解决方案
定价
更多

React使用express-fileupload时如何获取其他表单文本输入字段

React 结合 express-fileupload 上传文件时同时获取普通表单字段的实现方案

问题根因

当前的请求写法存在两个关键错误,直接导致普通表单字段无法被后端解析:

  1. axios.post 的参数规则是 axios.post(url, 请求体载荷, 配置项),现在代码把携带文件的 FormData 当请求体,把 monitor/contactos/excepciones 三个普通表单字段塞到了第三个参数(axios 配置项)的位置,这部分内容根本不会被发送到后端,自然 req.body 里找不到对应字段。
  2. 带文件上传的 multipart/form-data 格式请求不能直接传递JSON对象,所有非文件的普通字段必须全部追加到同一个 FormData 实例里,后端才能正确解析到对应值。

当不携带文件、直接把 {monitor, contactos, excepciones} 当JSON发请求时,express.json() 中间件会正常解析JSON请求体,所以 req.body 能拿到完整字段,req.files 自然是 undefined。
当只把文件塞进 FormData 发请求时,express-fileupload 中间件能正常解析 multipart 格式的请求拿到文件,但因为根本没把其他普通字段发到请求里,req.body 只有空对象,所以读取 req.body.monitor 时直接抛出 undefined 的属性读取错误。

前端正确实现

1. 统一收集所有字段到同一个 FormData 实例

嵌套对象、数组类型的字段不能直接 append,需要先做 JSON 字符串序列化,避免后端解析成纯字符串拿不到结构:

// 初始化FormData
const formData = new FormData();

// 追加文件字段
if (archivoSFTP) {
  formData.append('directorioFTP', archivoSFTP);
}

// 追加普通嵌套对象、数组字段,必须先转成JSON字符串
formData.append('monitor', JSON.stringify(monitor));
formData.append('contactos', JSON.stringify(contactos));
formData.append('exepciones', JSON.stringify(excepciones));

2. 正确发送axios请求

不需要手动设置 Content-Type,浏览器会自动根据 FormData 的内容设置正确的 multipart/form-data 边界值,手动设置反而会导致解析失败:

const response = await axios.post(
  'http://localhost:4000/api/monitor',
  formData // 所有请求载荷都放在第二个参数位置
  // 第三个参数是axios配置项,不要在这里塞业务字段
);

后端调整点

因为发给后端的嵌套对象、数组是 JSON 字符串格式,需要在路由处理时先把对应的字符串字段解析成原生对象,否则拿不到嵌套属性:

controladorMonitor.crear = async (req, res) => {
  // 先解析从FormData传来的JSON字符串字段
  const monitor = JSON.parse(req.body.monitor);
  const contactos = JSON.parse(req.body.contactos);
  const exepciones = JSON.parse(req.body.exepciones);

  // 打印验证,此时req.files能拿到上传的文件,req.body能拿到所有字符串字段
  console.log('上传文件:', req.files);
  console.log('普通字段:', req.body);

  const crearMonitor = new Monitor({
    generales: {
      urlSitio:                   monitor.urlSitio,
      userAgent:                  monitor.userAgent,
      cookieName:                 monitor.cookieName,
      validaURL:                  monitor.validaURL,
      monitoreaCada:              monitor.monitoreaCada,
      generarMinitatura:          monitor.generarMinitatura
    },
    maximoAlertas:                  monitor.maximoAlertas,
    contactos:                      contactos,
    exepcionesTexto:                exepciones,
    habilitarExepcionesTexto:       monitor.habilitarExepcionesTexto,
    antiDefaced:                    monitor.antiDefaced,
    integridadImagen:               monitor.integridadImagen,
    porcentajeIgualdad:             monitor.porcentajeIgualdad,
    porcentajeIgual:                monitor.porcentajeIgual,
    fuzzyHashing:                   monitor.fuzzyHashing,
    fuzzyHash:                      monitor.fuzzyHash,
    igualdad:                       monitor.igualdad,
    ftp:                            monitor.ipFTP,
    usuarioFTP:                     monitor.usuarioFTP,
    contraseniaFTP:                monitor.contraseniaFTP,
    directorioFTP:                  monitor.directorioFTP,
    puertoFTP:                      monitor.puertoFTP,
    ipSSH:                          monitor.ipSSH,
    usuarioSSH:                     monitor.usuarioSSH,
    contraseniaSSH:                 monitor.contraseniaSSH,
    directorioSSH:                  monitor.directorioSSH,
    puertoSSH:                      monitor.puertoSSH
  })

  try {
    await crearMonitor.save();
    if (!fse.existsSync(crearMonitor._id)) {
      fse.mkdirSync('archivos/'+crearMonitor._id)
    }
    res.status(201).json('Monitor creado exitosamente');
  } catch (err) {
    generateLog('db_error', err);
    res.status(400).json('Error en la petición')
  }
};

额外注意事项

  • 不要把 FormData 实例和普通JSON对象混在同一个请求体中发送,axios 会自动将传入 FormData 的请求识别为 multipart/form-data 格式,其他塞在请求体里的普通对象不会被正确序列化传递,最终后端会拿到空的请求体。
  • 不要手动给 axios 设置 Content-Type: multipart/form-data,浏览器会自动生成带 boundary 分隔标识的请求头,手动配置会导致后端中间件无法正确分割请求体,出现 req.body、req.files 全为空的异常。
  • 当前后端服务的中间件顺序是符合要求的:cors、日志、JSON解析、urlencoded解析、文件上传、静态服务,这个顺序不需要调整,express-fileupload 会自动处理 multipart 格式的请求,把文件挂载到 req.files、普通文本字段挂载到 req.body。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 15:45:05