Axios Patch请求后端userid参数为undefined问题求助
问题:Axios Patch调用更新数据失败,请求排查修复
我想用Axios的Patch请求更新服务器数据,但代码里的错误一直找不到,麻烦帮忙解决。我的需求是通过产品ObjectId编辑产品详情并保存到数据库,也接受其他实现方式,这个问题已经卡了2天了。
原代码
后端Node.js Express API代码
router.patch('/up',async (req, res) => { try{ const id = req.query.userid; // 用户objectid console.log(req.body) console.log(req.query.userid) const result= User.findById(id, (error, foundUser) => { if (foundUser) { const { products } = foundUser; const filteredproducts = products.filter((item) => { return item._id!= req.body.body._id; //产品数组的objectid }); while (foundUser.products.length > 0) { foundUser.products.pop(); } foundUser.products = filteredproducts; foundUser.products.push({ brandname: req.body.brandname, productname: req.body.productname, quantity: req.body.quantity, price: req.body.price, description: req.body.description }); foundUser.save(); } else { console.log('User not found') } }) res.status(200).send("update successfull"); } catch(err){ res.status(403).send('update unsuccessfull') console.log(err) } })
数据库User Schema代码
const userschema = new mongoose.Schema({ username: { type: String, }, email: { type: String, required: true }, place: { type: String, required: true }, password: { type: String, required: true }, products:[ { brandname: { type:String, required:true }, productname:{ type:String, required:true }, quantity:{ type:Number, required:true }, price:{ type:Number, required:true }, description:{ type:String, required:true } } ], tokens: [{ token: { type: String, required: true } }] }) const User = mongoose.model('USER', userschema)
前端React API代码
const updateproduct = async(req,res) => { console.warn(values.brandname, values.productname,values.quantity, values.price, values.description) console.warn("userlogin is:", userid) // 用户objectid const _id=id; // 产品objectid await axios.patch(`http://localhost:5000/up`,{ headers: { 'Content-type': 'application/json' }, data: {brandname,productname,quantity,price,description,_id}, //已通过控制台确认字段值正确 params:{ 'userid':userid } }, { withCredentials: true }) .then((res) => { console.log(res) navigate('/listproduct') }) .catch((err) => { console.log(err) }) }
修改记录(仍报错)
修改后后端API代码
router.patch('/up',async (req, res) => { try{ const id = req.query.userid; console.log("user id is",id) console.log("req.body",req.body.body.brandname) const result= User.findById(id, (error, foundUser) => { if (foundUser) { const { products } = foundUser; const filteredexpenses = products.filter((item) => { return item._id!= req.body.body._id; }); while (foundUser.products.length > 0) { foundUser.products.pop(); } foundUser.products = filteredexpenses; foundUser.products.push({ brandname: req.body.body.brandname, productname: req.body.body.productname, quantity: req.body.body.quantity, price: req.body.body.price, description: req.body.body.description }); foundUser.save(); } else { console.log('User not found') } }) res.status(200).send("update successfull"); } catch(err){ res.status(403).send('update unsuccessfull') console.log(err) } })
修改后前端API代码
const updateproduct = async(req,res) => { console.warn(values.brandname, values.productname,values.quantity, values.price, values.description) console.warn("userlogin is:", userid) const _id=id; await axios.patch(`http://localhost:5000/up`,{ headers: { 'Content-type': 'application/json' }, body: {'brandname':brandname,'productname':productname,'quantity':quantity,'price':price,'description':description,'_id':_id}, params:{ 'userid':userid } }, { withCredentials: true }) .then((res) => { console.log(res) navigate('/listproduct') }) .catch((err) => { console.log(err) }) }
控制台输出
User id is undefined req.body adidas //品牌名 User not found
问题分析与修复
核心问题点
- Axios参数格式错误:Axios的
patch方法参数顺序是url, data, config,你把headers、params都放到了第二个参数(data位置),导致userid参数没正确传到后端,所以后端req.query.userid是undefined。 - 产品ID匹配问题:Mongoose的ObjectId不能直接用
!=比较,需要用toString()或者equals()方法。 - 异步操作处理不当:
User.findById是异步的,你直接在回调外返回成功响应,可能数据库操作还没完成;而且foundUser.save()也没处理异步结果,可能保存失败没被捕获。 - 请求体结构混乱:前后端对请求体的层级不统一,一会用
req.body.body一会用req.body,导致字段读取错误。
修复后的代码
前端代码
const updateproduct = async () => { console.warn(values.brandname, values.productname, values.quantity, values.price, values.description); console.warn("userlogin is:", userid); const _id = id; try { const res = await axios.patch( `http://localhost:5000/up`, // 第一个参数:请求体数据 { brandname: values.brandname, productname: values.productname, quantity: values.quantity, price: values.price, description: values.description, _id }, // 第二个参数:请求配置(headers、params、跨域设置) { headers: { 'Content-type': 'application/json' }, params: { 'userid': userid }, withCredentials: true } ); console.log(res); navigate('/listproduct'); } catch (err) { console.log(err); } }
后端代码
router.patch('/up', async (req, res) => { try { const userId = req.query.userid; if (!userId) { return res.status(400).send('用户ID不能为空'); } console.log("user id is", userId); console.log("req.body", req.body); // 用async/await处理Mongoose异步操作,避免回调嵌套 const foundUser = await User.findById(userId); if (!foundUser) { console.log('User not found'); return res.status(404).send('用户不存在'); } const productId = req.body._id; // 过滤掉要修改的旧产品,用equals比较ObjectId foundUser.products = foundUser.products.filter(item => !item._id.equals(productId)); // 添加修改后的新产品 foundUser.products.push({ brandname: req.body.brandname, productname: req.body.productname, quantity: req.body.quantity, price: req.body.price, description: req.body.description }); // 等待保存完成,确保数据写入数据库 await foundUser.save(); res.status(200).send("更新成功"); } catch (err) { console.log(err); res.status(500).send('更新失败'); } });
额外优化建议
可以用Mongoose的findByIdAndUpdate直接更新,更高效,避免先查询再修改保存的冗余操作:
router.patch('/up', async (req, res) => { try { const userId = req.query.userid; // 解构出产品ID,剩余字段为更新后的产品数据 const { _id: productId, ...updatedProduct } = req.body; const updatedUser = await User.findByIdAndUpdate( userId, { $pull: { products: { _id: productId } }, // 删除旧产品 $push: { products: updatedProduct } // 添加新产品 }, { new: true, runValidators: true } // 返回更新后的文档,触发Schema验证 ); if (!updatedUser) { return res.status(404).send('用户不存在'); } res.status(200).send("更新成功"); } catch (err) { console.log(err); res.status(500).send('更新失败'); } });
内容的提问来源于stack exchange,提问作者Vysakh M Nair
相关产品推荐
相关产品推荐

