如何在提交时将一个表单的值传递至另一个表单?基于Handlebars视图与Node.js后端的第二表单数据保存实现咨询
解决你的两个Handlebars + Node.js开发问题
问题1:提交表单时将一个表单的值传递到另一个表单
从你的代码来看,你有一个检查子域名可用性的表单(对应/checkSubdomainAvailability路由),之后需要把institute_subdomain的值传递到创建机构的表单(/institute/create)。因为HTTP是无状态的,重定向后req.body的内容会丢失,所以我们可以用Session来暂存这个值,具体步骤如下:
在检查可用性的路由中保存值到Session
修改checkSubdomainAvailability路由,当子域名可用时,把institute_subdomain存入session,避免全局变量污染的同时保留数据:instituteRouter.post('/checkSubdomainAvailability', async (req, res) => { let { success, error, validationError } = req.session; const institute_subdomain = req.body.institute_subdomain; const response = await institute.findOne({ institute_subdomain: institute_subdomain }).exec(); if (response === null) { console.log('Subdomain is available'); req.session.success = 'Subdomain is available.' req.session.error = null; // 将子域名存入session暂存 req.session.institute_subdomain = institute_subdomain; return res.redirect("/institute/create"); } else { req.session.error = 'Subdomain is taken. Please try again.' req.session.success = null; return res.redirect("back"); } })在Handlebars创建表单中读取Session值
在创建表单里添加一个隐藏字段,把session中的institute_subdomain回传给后端,这样提交创建表单时就能携带这个值:{{> alertmessage}} <!-- 补充完整检查可用性的表单 --> <form class="form-horizontal" action="/institute/checkSubdomainAvailability" method="POST"> <div class="form-group"> <label for="subdomain" class="col-sm-2 control-label">Website Name* Check Availability</label> <div class="col-sm-10"> <div class="form-line"> <input type="text" class="form-control" id="institute_subdomain" name="institute_subdomain" placeholder="Enter subdomain" required> </div> </div> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-info">Check Availability</button> </div> </div> </form> <!-- 创建机构的表单 --> <form class="form-horizontal" action="/institute/create" method="POST"> <!-- 添加隐藏字段传递子域名 --> <input type="hidden" name="institute_subdomain" value="{{session.institute_subdomain}}"> <div class="form-group"> <label for="fullname" class="col-sm-2 control-label">Institute Name*</label> <div class="col-sm-10"> <div class="form-line"> <input type="text" class="form-control" id="institute_name" name="institute_name" placeholder="institute_name" value="{{institute.institute_name}}" required> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-success">Create</button> <a class="btn btn-warning" href="/adminusers">Go to adminusers</a> </div> </div> </form> </div> </div> </div> </div> </section>这样用户检查完可用子域名后,进入创建页面时隐藏字段会自动带上该值,提交表单时就能传给后端。
问题2:提交第二个表单时将数据保存到后端数据库
你的/create路由已有基本创建逻辑,但可以优化错误捕获和验证,确保数据稳定保存:
完善路由的错误捕获与验证
补充缺失的验证逻辑,用try/catch捕获数据库操作异常,避免程序崩溃:instituteRouter.post('/create', async (req, res) => { try { let { success, error, validationError } = req.session; // 验证子域名是否已通过检查(防止用户直接访问创建页面) if (!req.body.institute_subdomain) { req.session.error = 'Please check subdomain availability first.'; return res.redirect('/institute/create'); } // 验证机构名称不为空 if (!req.body.institute_name) { req.session.error = 'Institute name is required.'; return res.redirect('/institute/create'); } const pageToCreate = { institute_name: req.body.institute_name, institute_subdomain: req.body.institute_subdomain }; const createdPage = await institute.create(pageToCreate); if (createdPage) { req.session.success = 'Institute created successfully.'; // 清除session中的子域名,避免重复使用 delete req.session.institute_subdomain; return res.redirect('/institute'); } else { req.session.error = 'Error occurred in creating a new page'; return res.redirect('/institute/create'); } } catch (err) { console.error('Create institute error:', err); req.session.error = 'Database error: Failed to create institute.'; return res.redirect('/institute/create'); } })确保数据库模型配置正确
你的institute模型需要包含对应字段,并给子域名添加唯一性约束,防止重复数据:// 示例Mongoose模型 const mongoose = require('mongoose'); const instituteSchema = new mongoose.Schema({ institute_name: { type: String, required: true }, institute_subdomain: { type: String, required: true, unique: true } }); module.exports = mongoose.model('Institute', instituteSchema);这样数据库会自动验证子域名的唯一性,即使绕过前端检查也能保证数据一致性。
内容的提问来源于stack exchange,提问作者happy kaul




