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

使用ReactJS与Axios更新图片时提交FormData请求失败的问题

React + Axios 携带FormData格式图片发起PUT请求失败问题排查

问题表现

  • 实现带图片上传功能的患者信息更新PUT接口
  • 已通过原生FormData API转换上传的图片文件,但只要把图片数据加入请求参数,接口就会触发报错
  • 移除图片相关字段后,请求可正常调用后端API

原问题代码

表单提交方法

onSubmit = (e) => {
  e.preventDefault();
  let fd = new FormData();
  fd.append('image', this.state.images, this.state.images.name);
  console.log(fd);
  const { id, nom }  = this.state.patient;
  axios.put('/patients/' + this.props.match.params.id, {id, nom, fd})
    .then((result) => {
      this.props.history.push("/show/" + this.props.match.params.id)
      if (result.data != null){
        this.setState(this.initialState);
      }
    });
}

图片选择处理方法

handleFile(e) {
  this.setState({ images: e.target.files[0] });
  this.setState({ image: '' });
  let reader = new FileReader();
  let images = e.target.files[0];
  reader.onloadend = () => {
    this.setState({ file: images, imagePreviewUrl: reader.result });
  }
  reader.readAsDataURL(images)
}

问题根因定位

  • 请求体构造逻辑错误:原代码将FormData实例fd作为普通属性嵌套在纯JS对象{id, nom, fd}中传给Axios,Axios默认会将传入的普通JS对象序列化为JSON字符串,嵌套在内的FormData实例完全不会被正确解析为multipart表单结构,后端无法识别文件数据就会触发请求错误。
  • 请求头格式不匹配:默认请求会携带application/json的Content-Type头,和FormData要求的multipart/form-data格式不匹配,即使后端接收到请求也无法正确解析表单内容。

修正方案

  • 所有需要提交的字段(包括文本字段、文件字段)全部直接append到同一个FormData实例中,不要将FormData嵌套在普通JS对象里
  • 将完整的FormData实例直接作为请求体传给Axios,Axios会自动生成带边界标识的正确multipart/form-data请求头
    修正后的提交方法示例:
onSubmit = (e) => {
  e.preventDefault();
  let fd = new FormData();
  const { id, nom } = this.state.patient;
  // 文本字段直接append到FormData中
  fd.append('id', id);
  fd.append('nom', nom);
  // 仅当存在选中的图片文件时再append,避免空值导致的报错
  if (this.state.images) {
    fd.append('image', this.state.images, this.state.images.name);
  }
  // 直接将FormData实例作为请求体传给Axios
  axios.put('/patients/' + this.props.match.params.id, fd)
    .then((result) => {
      this.props.history.push("/show/" + this.props.match.params.id)
      if (result.data != null){
        this.setState(this.initialState);
      }
    });
}

常见踩坑提醒

  • 不要手动在请求头中写死Content-Type: multipart/form-data,浏览器和Axios会根据FormData的内容自动生成包含boundary参数的完整请求头,手动写死会导致boundary缺失,后端无法拆分解析各个表单字段。
  • FormData实例不能通过直接console.log打印出内部存储的字段值,调试时需要用fd.getAll('字段名')的方法查看实际存储的内容。
  • 调试时可在浏览器开发者工具的网络面板中查看请求Payload,确认所有字段是否以表单形式展示,而非被序列化成JSON字符串结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 21:45:05