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

React调用Express+Mongoose更新集合失败,Postman可正常运行

问题描述

通过React的fetch方法调用Express接口更新Mongoose集合,Postman测试接口可正常完成更新,但React调用后数据库集合无变化,也无任何报错,控制台返回的响应看起来正常。

核心原因分析

  1. 后端未解析FormData请求:React端发送的是FormData类型数据,Content-Type为multipart/form-data,而Express默认不处理该类型请求,且PUT路由未配置multer解析中间件,导致后端req.body为空,更新操作实际未执行。
  2. Mongoose更新默认返回旧文档:findByIdAndUpdate方法默认返回更新前的旧文档,即便后续修复解析问题,前端也会收到旧数据,容易误以为更新生效。
  3. 前端状态与请求数据不同步:使用FormData时,组件状态更新未同步FormData的引用,可能导致部分字段未被正确传入请求。

分步解决方案

1. 后端添加FormData解析中间件

在PUT路由中加入upload.none()中间件,用于解析不含文件的FormData文本字段:

// Pages路由修改
router.put("/admin/header/:headerId/:adminId", upload.none(), requireSignin, isAuth, updateHeader)

2. 配置Mongoose返回更新后的新文档

在findByIdAndUpdate中添加{ new: true }选项,确保接口返回更新后的最新数据:

// Pages控制器的updateHeader函数修改
Header.findByIdAndUpdate(
  {_id: headerId},
  {
    $set:{
      title: updatedTitle,
      brand: updatedBrand,
      description: updatedDescription,
    }
  },
  { new: true } // 新增此选项
)
.then((result)=> {
  console.log("Update is called")
  return res.status(200).json({
    message: "Header is updated", result
  })
})

3. 前端改用JSON格式发送请求(推荐,无需FormData)

若无需上传文件,改用JSON格式更符合常规API设计,避免FormData解析问题:

// React核心API的updateHeader修改
export const updateHeader = (headerId, adminId, token, header) => {
  return fetch(`${API}/admin/header/${headerId}/${adminId}`, {
    method: "PUT",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify(header),
  })
    .then((response) => {
      console.log(response)
      return response.json();
    })
    .catch((err) => console.log(err));
};

同时修改React组件的事件处理逻辑,不再依赖FormData:

// React更新组件的handleChange修改
const handleChange = name => event => {
  const value = event.target.value;
  setValues({ ...values, [name]: value });
};

// clickSubmit修改
const clickSubmit = event => {
  event.preventDefault();
  setValues({ ...values, error: '', loading: true });

  const headerData = { title, brand, description };
  console.log("发送的更新数据:", headerData); // 调试用

  updateHeader(headerId, admin._id, token, headerData).then(data => {
    if (data.error) {
      console.log(data.error)
      setValues({ ...values, error: data.error });
    } else {
      setValues({
        ...values,
        title: '',
        brand: '',
        description: '',
        loading: false,
        error: false,
        redirectToProfile: true,
        createdHeader: data.title
      });
    }
  });
};

4. 必要的调试步骤

  • 后端updateHeader函数中打印req.body,确认是否接收到数据:
exports.updateHeader = (req,res,next)=>{
  console.log("接收到的请求体:", req.body); // 调试用
  const headerId = req.params.headerId 
  // ... 后续代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 03:55:54