You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在提交时将一个表单的值传递至另一个表单?基于Handlebars视图与Node.js后端的第二表单数据保存实现咨询

解决你的两个Handlebars + Node.js开发问题

问题1:提交表单时将一个表单的值传递到另一个表单

从你的代码来看,你有一个检查子域名可用性的表单(对应/checkSubdomainAvailability路由),之后需要把institute_subdomain的值传递到创建机构的表单(/institute/create)。因为HTTP是无状态的,重定向后req.body的内容会丢失,所以我们可以用Session来暂存这个值,具体步骤如下:

  1. 在检查可用性的路由中保存值到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");
      }
    })
    
  2. 在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路由已有基本创建逻辑,但可以优化错误捕获和验证,确保数据稳定保存:

  1. 完善路由的错误捕获与验证
    补充缺失的验证逻辑,用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');
      }
    })
    
  2. 确保数据库模型配置正确
    你的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

火山引擎 最新活动