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

使用Axios发送Put请求携带FormData时出现undefined is not Json错误

使用Axios发送带FormData的PUT请求时出现「undefined is not Json」错误的解决

问题描述

使用Axios发送携带FormData对象的PUT请求后,出现「undefined is not Json」错误。已确认前端updatedData不为空且包含所需数据,但后端console.log(req.body)显示req.body={}为空对象,进而触发错误。

相关代码

updatedData构建代码

const urlToObject = async (url) => {
  let response = await fetch(url);
  let blob = await response.blob();
  return new File([blob], data?.photo, { type: blob.type });
};
const picture = await urlToObject(STABLES.UPLOAD_FOLDER_BASE_URL + data?.photo);
updatedData.append("mainPhoto", picture);
const emptyDocument = JSON.stringify({
      title: "",
      caption: "",
      slug: "",
      body: "",
      tags: [],
      categories: [],
});
updatedData.append("document", emptyDocument);

请求函数代码

const updatePost = async  ({ updatedData, slug, token }) => {
      try {
        const config = {
          headers: {
           "Content-Type": "multipart/form-data",
            Authorization: `Bearer ${token}`,
          }
        };

        const { data } = await axios.put(`/api/posts/${slug}`, updatedData, config);
        return data;
      } catch (e) {
        if(e.response && e.response.data.message) {
          throw new Error(e.response.data.message);
        }
        throw new Error(e.message);
      }
    };

已尝试的无效方案

  • 修改Content-Type为application/x-www-form-urlencoded
  • 修改Content-Type为application/json,此时仅能获取req.body.document,但无法拿到mainPhoto图片文件
  • 在server.js中添加以下Express中间件,问题未解决:
    app.use(express.json());
    app.use(express.urlencoded({ extended: true }));
    app.use(express.json({ limit: '10mb' }));
    app.use(express.urlencoded({ limit: '10mb', extended: true }));
    

正确解决方案

前端调整

不要手动设置Content-Type: multipart/form-data,Axios会自动为FormData请求添加包含边界符boundary的正确Content-Type,手动设置会丢失边界信息,导致后端无法解析。修改请求函数如下:

const updatePost = async ({ updatedData, slug, token }) => {
  try {
    const config = {
      headers: {
        Authorization: `Bearer ${token}`,
        // 移除手动设置的Content-Type
      }
    };

    const { data } = await axios.put(`/api/posts/${slug}`, updatedData, config);
    return data;
  } catch (e) {
    if(e.response && e.response.data.message) {
      throw new Error(e.response.data.message);
    }
    throw new Error(e.message);
  }
};

后端调整

Express默认的express.json()和express.urlencoded()无法解析multipart/form-data类型请求,需使用multer中间件处理文件上传:

  1. 安装multer:
    npm install multer
    
  2. 在后端路由中配置multer:
    const multer = require('multer');
    const upload = multer(); // 默认将文件暂存到内存,可按需修改存储方式
    
    // 在PUT请求路由中使用upload中间件
    app.put('/api/posts/:slug', upload.any(), (req, res) => {
      // req.body 包含document字段(需手动转为JSON)
      // req.files 包含mainPhoto文件对象
      const document = JSON.parse(req.body.document);
      const mainPhoto = req.files.find(file => file.fieldname === 'mainPhoto');
      // 后续业务逻辑处理
    });
    
    若需持久化存储文件,可配置multer的磁盘存储引擎:
    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, 'uploads/') // 指定存储目录,需提前创建
      },
      filename: function (req, file, cb) {
        cb(null, Date.now() + '-' + file.originalname) // 生成唯一文件名
      }
    });
    const upload = multer({ storage: storage });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:15:20