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

React中使用json-server处理multipart/form-data POST请求失败求助

React中multipart/form-data上传文件到json-server失败问题排查与修复

我在React中编写了上传视频和图片文件的POST方法,但使用multipart/form-data格式对接json-server时无法正常工作,无法获取期望的数据。以下是我的POST方法和提交方法代码:

const ApiUrl = "http://localhost:8000/";

export const sshOpenServiceRequest = async (jsonData) => {
    return axios.post(ApiUrl + `serviceList`, jsonData,
      {
        headers: {
          ContentType: "multipart/form-data",
        }
      })
    .then((response) => {
      return response;
    })
    .catch(() => {
      return false;
    });
};

// 提交方法
const handleSubmit = async () => {
    //const isValid = checkValid();
    //if (isValid) {
      setIsSubmitting(true);

      const formData = new FormData();
      formData.append("materialCode", matCode);
      formData.append("channel", channel);
      formData.append("warehouseUnitCode", wareHouseUnit);

      for (const key in photos) {
        if (Object.hasOwnProperty.call(photos, key)) {
          const element = photos[key];
          formData.append(`images`, element);
        }
      }

      for (const key in videos) {
        if (Object.hasOwnProperty.call(videos, key)) {
          const element = videos[key];
          formData.append(`videos`, element);
        }
      }
      try {
        const result = await sshOpenServiceRequest(formData);
        console.log(result);
        if (result.data.success) {
          //history.push("/ssh-list/");
          notify("Form isteği başarılı");
        } else {
          notify("Form isteği başarısız");
        }
      } catch (error) {
        notify("Form isteği başarısız");
      }

      setIsSubmitting(true);
    //}
};

问题分析

  1. 请求头配置错误:你在headers中写的ContentType是错误的键名,正确应为Content-Type。更关键的是,当传递FormData给Axios时,Axios会自动生成包含boundary的正确Content-Type,手动设置反而会丢失boundary,导致服务端无法解析表单数据。
  2. json-server原生限制:json-server默认只支持处理JSON格式的请求,不具备解析multipart/form-data和处理文件上传的能力,需要额外配置中间件。
  3. 提交状态逻辑错误:最后一行setIsSubmitting(true)应该改为setIsSubmitting(false),否则提交状态会一直处于激活状态。

修复方案

1. 修正Axios请求函数

移除手动设置的Content-Type,让Axios自动处理:

const ApiUrl = "http://localhost:8000/";

export const sshOpenServiceRequest = async (formData) => {
  try {
    const response = await axios.post(ApiUrl + `serviceList`, formData);
    return response;
  } catch (error) {
    console.error('请求错误:', error);
    return false;
  }
};

2. 修正提交方法的状态逻辑

const handleSubmit = async () => {
  setIsSubmitting(true);

  const formData = new FormData();
  formData.append("materialCode", matCode);
  formData.append("channel", channel);
  formData.append("warehouseUnitCode", wareHouseUnit);

  for (const key in photos) {
    if (Object.hasOwnProperty.call(photos, key)) {
      const element = photos[key];
      formData.append(`images`, element);
    }
  }

  for (const key in videos) {
    if (Object.hasOwnProperty.call(videos, key)) {
      const element = videos[key];
      formData.append(`videos`, element);
    }
  }
  
  try {
    const result = await sshOpenServiceRequest(formData);
    console.log(result);
    if (result?.data?.success) {
      notify("表单请求成功");
      // history.push("/ssh-list/");
    } else {
      notify("表单请求失败");
    }
  } catch (error) {
    console.error('提交错误:', error);
    notify("表单请求失败");
  } finally {
    setIsSubmitting(false); // 修正状态为false
  }
};

3. 配置json-server支持文件上传

使用multer中间件扩展json-server的能力:

  1. 安装依赖:
npm install multer json-server
  1. 创建自定义server.js文件:
const jsonServer = require('json-server');
const multer = require('multer');
const path = require('path');

const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();

// 配置文件存储目录
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads'); // 提前创建uploads目录
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname);
  }
});

const upload = multer({ storage: storage });

// 自定义处理文件上传的路由
server.post('/serviceList', upload.any(), (req, res) => {
  const formFields = req.body;
  const files = req.files;

  // 整理要保存的数据,包含文件路径
  const dataToSave = {
    ...formFields,
    images: files.filter(f => f.fieldname === 'images').map(f => `/uploads/${f.filename}`),
    videos: files.filter(f => f.fieldname === 'videos').map(f => `/uploads/${f.filename}`),
    success: true
  };

  // 写入json-server的数据库
  router.db.get('serviceList').push(dataToSave).write();
  res.json(dataToSave);
});

server.use(middlewares);
server.use(router);
server.listen(8000, () => {
  console.log('JSON Server 运行在 8000 端口');
});
  1. 启动自定义服务器:
node server.js

内容的提问来源于stack exchange,提问作者Can Çatalbaş

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:52:12