使用express-hbs时,表单数据无法完整存入Mongoose数据库求助
解决MongoDB仅存入date字段、title/content无法持久化的问题
问题场景
我正尝试将静态网站改造为动态网站,使用express-hbs框架。定义了包含title、content、date三个字段的Mongoose Schema,代码如下:
const PostSchema = new mongoose.Schema ({ title: {type: String, require: true}, content: {type: String, rqeuire: true}, date: { type: Date, default: Date.now} })
对应的hbs模板代码:
<div class="row"> {{#each posts}} <div class="col-md-6"> <div class="blog"> <div class="blog-img"> <img src="img/blog2.jpg" class="img-fluid"> </div> <div class="blog-content"> <ul class="blog-meta"> <li><i class="fas fa-users"></i><span class="writer">{{title}}</span></li> <li><i class="fas fa-clock"></i><span class="writer">{{date}}</span></li> <li><i class="fas fa-comments"></i><span class="writer">13</span></li> </ul> <h3>{{title}}</h3> <p>{{content}}</p> <a href="blog-single.html">Read More</a> </div> </div> </div> {{/each}}
POST路由代码:
router.post("/test" , (req,res) => { Post.create(req.body) res.redirect("/") })
但在MongoDB Compass中仅能看到date字段被存入,title和content仅成功存入过一次,后续提交的这两个字段均无法存入数据库。
排查与修复步骤
1. 修正Schema中的拼写错误
你的Schema里字段验证规则的属性名存在两处拼写错误:
require应为requiredrqeuire(content字段)应为required
Mongoose会忽略拼写错误的属性,导致title和content的必填验证不生效,同时无法正确识别字段规则。修正后的Schema:
const PostSchema = new mongoose.Schema ({ title: {type: String, required: true}, content: {type: String, required: true}, date: { type: Date, default: Date.now} })
2. 确保Express配置请求体解析中间件
如果Express应用未配置请求体解析,req.body会是空对象或undefined,导致只有默认的date字段被存入。需要在路由定义前添加以下中间件:
// 解析表单提交的urlencoded格式请求体 app.use(express.urlencoded({ extended: true })); // 解析JSON格式请求体(可选,若有AJAX提交需求) app.use(express.json());
3. 处理异步操作与错误捕获
Post.create是异步操作,直接调用后立即重定向会导致操作未完成就跳转,且无法捕获错误。修改路由代码:
router.post("/test" , async (req,res) => { try { await Post.create(req.body); res.redirect("/"); } catch (err) { console.error("创建文章失败:", err); res.status(500).send("创建文章失败,请重试"); } })
通过async/await等待数据库操作完成,同时捕获错误,便于调试定位问题(如字段验证失败、数据库连接异常等)。
4. 验证前端表单字段名
检查前端表单的name属性是否与Schema字段名完全一致(title和content),如果表单字段名拼写错误,req.body将无法获取对应值。示例表单结构:
<form action="/test" method="POST"> <input type="text" name="title" placeholder="文章标题"> <textarea name="content" placeholder="文章内容"></textarea> <button type="submit">提交</button> </form>
内容的提问来源于stack exchange,提问作者metkopetru
相关产品推荐
相关产品推荐

