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

MERN栈如何正确发送PUT请求更新数据及路由命名疑问

路由单复数说明

Express本身没有强制要求路由用单数还是复数,这只是RESTful API的通用命名约定,完全可以根据自己的需求自定义路由:

  • 一般操作资源集合(查询全量列表、新增资源)用复数命名,比如GET /animals查询所有动物、POST /animals/new新增动物
  • 操作单个资源(修改、删除指定id的资源)用单数+id命名,比如PUT /animal/update/:id更新单个动物、DELETE /animal/delete/:id删除单个动物
    你看到的教程里/users和/user/new的区别只是教程的写法,不是Express的固有特性,自己项目里只要保持命名统一即可。

PUT请求实现修复

服务端代码问题修复

你现有server.js里的PUT路由存在两个错误:findOne需要传入查询条件对象,不能直接传id;且写死了更新值,没有读取请求体的参数,修改为:

app.put('/animal/update/:id', async (req, res) => {
  try {
    // 正确查询指定id的动物数据
    const targetAnimal = await Animal.findById(req.params.id);
    if (!targetAnimal) return res.status(404).json({msg: '对应动物不存在'});
    // 从请求体读取要更新的字段,没有传的字段保留原值
    targetAnimal.phoneNumber = req.body.phoneNumber || targetAnimal.phoneNumber;
    targetAnimal.name = req.body.name || targetAnimal.name;
    targetAnimal.textHistory = req.body.textHistory || targetAnimal.textHistory;
    await targetAnimal.save();
    res.json(targetAnimal);
  } catch (err) {
    res.status(500).json({error: err.message});
  }
})

前端代码问题修复

你现有App.js里的changePhone方法没有指定PUT请求方式,调用路径也和你写的服务端路由不匹配,修改为:

const changePhone = async id => {
  const updatedAnimal = await fetch(api_base + '/animal/update/' + id, {
    method: "PUT",
    headers: {"Content-Type": "application/json" },
    // 把要更新的字段放到请求体
    body: JSON.stringify({
      phoneNumber: "bensonhurst"
    })
  }).then(res => res.json());
  // 遵循state不可变原则,返回新数组而不是修改原对象
  setAnimals(animals => animals.map(animal => {
    return animal._id === updatedAnimal._id ? {...animal, phoneNumber: updatedAnimal.phoneNumber} : animal;
  }));
}

给Animal模型添加子数组功能

第一步修改模型定义

以添加疫苗记录子数组为例,修改Animal.js:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const AnimalSchema = new Schema({
  phoneNumber: {type: String,required: false},
  textHistory: {type: String,required: false},
  name: {type: String,required: false},
  // 新增子数组字段
  vaccinationRecords: [{
    vaccineName: String,
    injectDate: Date,
    hospital: String
  }]
});

const Animal = mongoose.model("Animal", AnimalSchema);
module.exports = Animal;

第二步添加子数组新增接口

在server.js里新增路由,用MongoDB的$push操作符往数组添加元素:

app.put('/animal/add-vaccine/:id', async (req, res) => {
  try {
    const updatedAnimal = await Animal.findByIdAndUpdate(
      req.params.id,
      { $push: { vaccinationRecords: req.body.newVaccine } },
      { new: true } // 配置项:返回更新后的完整文档
    );
    res.json(updatedAnimal);
  } catch (err) {
    res.status(500).json({error: err.message});
  }
})

前端调用该接口时,在请求体传入对应的newVaccine对象即可完成子数组数据新增。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:15:07