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

API的PUT方法无法通过req.body更新User模型money字段问题

PUT接口money字段更新失败问题修复

核心问题点

  • findOneAndUpdate默认返回更新前的旧文档,不加配置的情况下接口永远返回修改前的数据,很容易误判为更新没生效。
  • Mongoose Schema默认开启strict严格模式,传入字段和Schema定义类型不匹配时会被静默过滤,不会写入数据库。当前Schema中money为Number类型,如果测试时传的是字符串格式的数值(比如接口测试工具默认传了文本类型的"300"),该字段会被直接丢弃,不会执行更新。
  • Schema存在字段类型错误:email被定义为SchemaTypes.Number,正常邮箱为字符串格式,目前能更新只是测试时刚好传了数字值、类型匹配才生效。
  • 代码存在安全风险:直接把整个req.body透传给$set,没有做字段白名单限制,用户可以随意篡改luck这类未开放修改的字段。

修复代码

1. 修改PUT接口逻辑

文件路径:/api/[id].ts

case "PUT":
      try {
        // 仅提取允许前端修改的字段,禁止直接透传整个req.body
        const { money, email, name, image } = req.body;
        const updateData: Record<string, unknown> = {};
        
        // 对字段做类型转换和校验,避免类型不匹配被Mongoose过滤
        if (money !== undefined) {
          const moneyVal = Number(money);
          if (!isNaN(moneyVal)) updateData.money = moneyVal;
        }
        if (email !== undefined) updateData.email = email;
        if (name !== undefined) updateData.name = name;
        if (image !== undefined) updateData.image = image;

        const user = await UserModel.findOneAndUpdate(
          { _id: id },
          { $set: updateData },
          {
            new: true, // 配置返回更新后的新文档,而非更新前的旧数据
            runValidators: true // 开启更新操作的Schema校验,拦截非法数据
          }
        );

        if (!user) {
          return res.status(404).json({ success: false, msg: "用户不存在" });
        }

        res.status(200).json(user);
      } catch (error) {
        res.status(400).json({ success: false, msg: (error as Error).message });
      }
      break;

2. 修正Schema字段类型

文件路径:models/UserModel.ts

import { model, models, Schema, SchemaTypes } from "mongoose";

const UserSchema = new Schema({
  name: {
    type: SchemaTypes.String,
    required: true,
  },
  email: {
    type: SchemaTypes.String, // 修正:邮箱为字符串类型,不是数字
    required: false,
  },
  image: {
    type: SchemaTypes.String,
    required: true,
  },
  emailVerified: {
    type: SchemaTypes.Date, // 若存时间戳可保留Number,常规逻辑下邮箱验证状态为时间日期类型
    required: false,
  },
  money: {
    type: SchemaTypes.Number,
    required: true,
    default: 100,
  },
  luck: {
    type: SchemaTypes.Number,
    required: true,
    default: 1,
  },
});

export default models.User || model("User", UserSchema);

验证注意事项

  • 接口测试时确认money参数为数字类型,不要传字符串格式的数值
  • 调用接口后返回的是更新后的最新文档,可同步查库确认字段值是否变更
  • 不要传未在白名单内的字段,避免非预期更新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:54:31