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

如何通过Axios单次POST请求同时提交FormData对象与文件至Spring Boot接口

结论

  • 你要求的「不把文件追加到FormData对象,单次POST同时传业务对象和文件」的需求无法通过标准HTTP协议实现,可选的替代方案只有将文件转Base64塞进JSON请求体,该方案会让文件体积膨胀30%左右,仅适合极小体积的音频文件,不推荐生产环境使用。
  • 把文件追加到FormData的方案不会导致后端报错,是目前同时传二进制文件和结构化数据的标准实现,你Postman里的请求本质也是走的这个逻辑,只是你当前的前端代码写法不匹配后端接口规则才会调用失败。

后端接口规则说明

你的后端控制器用@RequestPart定义了两个请求部分:

  1. 键名为soundProfileRequest、类型为JSON的业务对象
  2. 键名为audio_file、类型为二进制的音频文件

你当前的前端代码是把业务对象的每个字段单独追加到FormData,和后端期望的结构不匹配,所以会报错。

正确的前端代码修改

const createSoundProfile = (e) => {
    e.preventDefault();
    const url = "/sound-profile/upload";
    const formData = new FormData();

    // 1. 构造业务对象,转成JSON Blob追加到FormData
    const soundProfileRequest = {
        caseBrand,
        caseModel,
        switches,
        keycaps,
        lube,
        stabilizers,
        mods
    };
    formData.append('soundProfileRequest', 
        new Blob([JSON.stringify(soundProfileRequest)], {type: 'application/json'})
    );

    // 2. 追加音频文件
    formData.append('audio_file', selectedFile);

    // 注意:不需要手动设置Content-Type,浏览器会自动生成带boundary的正确请求头
    const config = {};

    uploadProfileService.createSoundProfile(url, formData, config)
        .then(() => {
            history.push("/sound-profile/profile");
        })
        .catch(err => {
            // 这里加错误处理逻辑,避免请求失败还跳转
            console.error("上传失败", err);
        });
};

额外优化建议

你控制器上的consumes配置可以去掉MediaType.APPLICATION_JSON_VALUE,因为你同时要求请求头Content-Type=multipart/form-data,JSON类型的请求不会匹配该接口,留着反而容易造成误解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:06:07