如何通过Sequelize ORM将HTML表单数据提交至PostgreSQL表
问题排查与修复方案
1. 前端HTML表单修复
原有表单存在三处核心问题:
- 未指定
method="POST",默认GET请求参数会拼接在URL中,后端无法从req.body获取提交数据 - 所有输入框仅配置了
id属性,缺少表单提交必需的name属性 - 缺少密码一致性校验逻辑,无提交事件拦截
修复后的代码如下:
<form action="http://localhost:3000/register" method="POST" id="registerForm"> <fieldset class="p-4"> <input type="email" placeholder="Email*" name="email" id="email" class="border p-3 w-100 my-2" required> <input type="password" placeholder="Password*" name="password" id="password" class="border p-3 w-100 my-2" required> <input type="password" placeholder="Confirm Password*" name="con_password" id="con_password" class="border p-3 w-100 my-2" required> <div class="loggedin-forgot d-inline-flex my-3"> <input type="checkbox" id="registering" class="mt-1" required> <label for="registering" class="px-2">By registering, you accept our <a class="text-primary font-weight-bold" href="terms-condition.html">Terms & Conditions</a></label> </div> <button type="submit" class="d-block py-3 px-4 bg-primary text-white border-0 rounded font-weight-bold">Register Now</button> </fieldset> </form> <script> document.getElementById('registerForm').addEventListener('submit', e => { const pwd = document.getElementById('password').value; const conPwd = document.getElementById('con_password').value; if(pwd !== conPwd) { alert('两次输入的密码不一致'); e.preventDefault(); } }) </script>
2. 后端逻辑修正
核心错误:接口路由不能写在Sequelize种子文件中,种子文件仅用于初始化数据库预置数据,业务接口需要写在Express服务主文件内。
依赖安装确认
先确保已安装所需依赖:
npm install express bcryptjs sequelize pg pg-hstore
新增RegisterUser模型文件 models/registeruser.js
Sequelize需要对应表的模型才能完成增删改查操作:
'use strict'; const { Model } = require('sequelize'); module.exports = (sequelize, DataTypes) => { class RegisterUser extends Model { static associate(models) {} } RegisterUser.init({ email: DataTypes.STRING, password: DataTypes.STRING, con_password: DataTypes.STRING }, { sequelize, modelName: 'RegisterUser', tableName: 'RegisterUsers' }); return RegisterUser; };
修正种子文件 seeds/20210823074536-Users.js
删除路由代码,仅保留初始化测试数据逻辑:
module.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.bulkInsert('RegisterUsers', [{ email: 'test@example.com', password: '$2a$10$rH7xKvY8zX9yWvU7tS6rR5qP4oN3mO2nL1kK0jJ9iH8gF7eD6c5b4', con_password: '$2a$10$rH7xKvY8zX9yWvU7tS6rR5qP4oN3mO2nL1kK0jJ9iH8gF7eD6c5b4', createdAt: new Date(), updatedAt: new Date() }]) }, down: async (queryInterface, Sequelize) => { await queryInterface.bulkDelete('RegisterUsers', null, {}); } };
主服务入口文件 app.js 配置
在服务入口文件中编写注册接口逻辑,同时配置请求体解析中间件:
const express = require('express'); const bcrypt = require('bcryptjs'); const RegisterUser = require('./models/registeruser'); const app = express(); const port = 3000; // 必须配置这两个中间件才能正常解析请求体 app.use(express.urlencoded({ extended: true })); app.use(express.json()); // 注册接口逻辑 app.post('/register', async(req,res)=>{ const { email, password: plainTextPassword } = req.body; if(!email || !plainTextPassword) { return res.status(400).send('邮箱和密码不能为空'); } try { const password = await bcrypt.hash(plainTextPassword,10); await RegisterUser.create({ email, password, con_password: password }); res.send('注册成功'); } catch(error) { console.log(error); res.status(500).send('注册失败,请重试'); } }); app.listen(port, () => { console.log(`服务运行在 http://localhost:${port}`); });
3. 补充说明
- 现有迁移文件逻辑正确无需修改,确认已执行
npx sequelize-cli db:migrate完成表创建 - 实际业务中无需保存确认密码字段到数据库,前端校验通过后可直接删除该字段减少冗余
- 后续可新增邮箱唯一性校验,避免重复注册
内容的提问来源于stack exchange,提问作者Palani Pavan
相关产品推荐
相关产品推荐

