React调用Express+Mongoose更新集合失败,Postman可正常运行
问题描述
通过React的fetch方法调用Express接口更新Mongoose集合,Postman测试接口可正常完成更新,但React调用后数据库集合无变化,也无任何报错,控制台返回的响应看起来正常。
核心原因分析
- 后端未解析FormData请求:React端发送的是
FormData类型数据,Content-Type为multipart/form-data,而Express默认不处理该类型请求,且PUT路由未配置multer解析中间件,导致后端req.body为空,更新操作实际未执行。 - Mongoose更新默认返回旧文档:
findByIdAndUpdate方法默认返回更新前的旧文档,即便后续修复解析问题,前端也会收到旧数据,容易误以为更新生效。 - 前端状态与请求数据不同步:使用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
相关产品推荐
相关产品推荐

