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

React发送含JSON与文件的FormData报错,如何排查解决?

前端React + Spring Boot 多表单请求问题排查修复

问题现象

前端使用React通过FormData发送包含图片和JSON数据的POST请求到Spring Boot后端,Postman测试接口正常,但浏览器请求时报错:"message": "Required request part 'swimArea' is not present",即使移除文件相关代码,错误依然存在。

核心问题与修复方案

1. 重复JSON序列化导致数据格式错误

你的前端代码中,swimArea已经是手动拼接的JSON字符串,却又调用了JSON.stringify()二次序列化,导致最终传递给后端的是转义后的嵌套字符串(例如"{\"swimArea\": {...}}"),后端无法将其解析为AddBathingPlaceRequest对象,因此识别不到swimArea参数。

修复:
去掉多余的JSON.stringify(),或者更规范地先定义JS对象再序列化:

// 方式1:直接使用已有的JSON字符串,无需二次序列化
const swimArea = "{\"swimArea\" : {\"name\": \"aTESTTEST\", \"longitude\": \"15.47\", \"latitude\": \"56.25\"}}";
formData.append('swimArea', swimArea);

// 方式2(推荐):先定义JS对象,再统一序列化,避免手动拼接JSON出错
const swimAreaObj = {
  swimArea: {
    name: "aTESTTEST",
    longitude: "15.47",
    latitude: "56.25"
  }
};
formData.append('swimArea', JSON.stringify(swimAreaObj));

2. 手动设置请求头导致解析失败

当使用FormData作为fetch请求的body时,浏览器会自动生成正确的multipart/form-data请求头,包括自动生成的boundary分隔符。你手动设置的Content-Type会覆盖自动生成的头,导致boundary不匹配,后端无法正确解析表单数据。

另外,Access-Control-Allow-*系列头是后端响应头,前端请求中添加这些头没有任何作用,反而可能干扰请求。

修复:
移除手动设置的Content-Type和CORS相关请求头:

const requestOptions = {
  method: "POST",
  // 仅保留必要的请求头(如Authorization,无则可省略headers)
  headers: {
    // "Authorization": "Bearer xxx" // 如果需要身份验证的话
  },
  body: formData,
};

3. 文件获取方式错误

e.target.file的写法不正确,input[type="file"]的文件需要通过files属性获取,正确写法为e.target.elements.file.files[0](假设你的文件输入框name或id为file)。

修复:

formData.append("file", e.target.elements.file.files[0]);

修改后的完整前端代码

const submitForm = (e: any) => {
    e.preventDefault();

    // 推荐使用JS对象序列化的方式
    const swimAreaObj = {
        swimArea: {
            name: "aTESTTEST",
            longitude: "15.47",
            latitude: "56.25"
        }
    };
    const formData = new FormData();
    formData.append('swimArea', JSON.stringify(swimAreaObj));
    // 正确获取文件
    formData.append("file", e.target.elements.file.files[0]);

    const requestOptions = {
        method: "POST",
        // 移除多余的请求头,由浏览器自动生成multipart/form-data头
        body: formData,
    };
    fetch(
        "http://localhost:8080/api/v1/bathplace/newBathingPlace",
        requestOptions
    )
        .then((response) => response.json())
        .then((data) => {
            // 处理返回数据
        })
        .catch(err => console.error("请求错误:", err));
};

验证步骤

  1. 打开浏览器开发者工具(F12),切换到Network标签;
  2. 触发请求,查看对应的POST请求;
  3. 检查Headers中的Content-Type是否为multipart/form-data; boundary=----WebKitFormBoundaryxxxx(由浏览器自动生成);
  4. 查看Form Data部分,确认swimArea的值是正确的JSON字符串,而非转义后的嵌套字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:10:54