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

Node.js YelpCamp项目更新露营地时触发"campground is required"校验错误求助

错误原因

你的Joi校验逻辑明确要求请求体顶层必须包含必填的campground对象,用于包裹露营地的title、price、location、description等字段。触发报错的核心原因是提交更新请求时,实际传入的req.body中不存在campground属性,导致校验不通过。
最常见的诱因是前端表单字段未加命名前缀:你编写更新表单时,输入框的name属性直接写了title、price这类字段名,没有加campground[xxx]的前缀,Express的urlencoded中间件就不会把这些字段聚合为req.body.campground对象。

修复方案

方案1:修改前端表单字段命名(推荐,适配现有逻辑)

将更新页面中所有露营地相关输入框的name属性,添加campground[ ]前缀,示例如下:

<!-- 修改前 -->
<input type="text" name="title" placeholder="露营地名称">
<input type="number" name="price" placeholder="价格">

<!-- 修改后 -->
<input type="text" name="campground[title]" placeholder="露营地名称">
<input type="number" name="campground[price]" placeholder="价格">

修改后请求提交时,字段会自动聚合为req.body.campground对象,匹配现有Joi校验规则,无需修改后端代码。

方案2:调整后端校验与业务逻辑(无需修改前端)

如果不想改动前端传参结构,直接修改后端的Joi规则和更新逻辑即可:

  1. 修改Joi校验规则,移除外层campground对象的嵌套要求:
const Joi = require('joi');
module.exports.campgroundSchema = Joi.object({
    title: Joi.string().required(),
    price: Joi.number().required().min(0),
    location: Joi.string().required(),
    description: Joi.string().required()
});
  1. 修改更新露营地的业务代码,直接从req.body取字段:
module.exports.updateCampground = async (req, res) => {
    const { id } = req.params;
    // 把原来的req.body.campground改为req.body
    const campgrounds = await campground.findByIdAndUpdate(id, { ...req.body });
    const imgs = req.files.map((f) => ({ url: f.path, filename: f.filename }));
    campgrounds.images.push(...imgs);
    await campgrounds.save();
    req.flash('success', 'Successfully updated Campground');
    res.redirect(`/campgrounds/${campgrounds._id}`);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:39:00