原生JS登录注册表单连MySQL失败,是否需handleChange/onSubmit?
问题解答:原生JS表单无需React的handleChange/onSubmit函数
你完全不需要用React的handleChange或onSubmit函数——这俩是React框架封装的表单处理逻辑,原生JS用自身的事件监听机制就足够。你的代码无法正常运行,是因为存在几个关键错误,逐个修复就能解决问题:
前端代码问题与修复
- DOM元素获取错误
- HTML里用户名输入框的id是
nom,但你JS里用了getElementById('name'),根本拿不到目标元素;而且你获取的是DOM节点本身,不是用户输入的内容,必须加.value才能拿到输入值。
- HTML里用户名输入框的id是
- 未阻止表单默认提交行为
- 点击按钮会触发form标签自带的POST提交(由HTML里的
method和action属性导致),页面会直接刷新,中断你的fetch请求。
- 点击按钮会触发form标签自带的POST提交(由HTML里的
- Fetch请求逻辑混乱
- console.log写在了fetch请求的then链外部,无法正确打印请求相关数据,且未处理请求错误情况。
修复后的前端JS代码:
const usernameInput = document.getElementById('nom'); const emailInput = document.getElementById('email'); const passwordInput = document.getElementById('password'); const form = document.querySelector('form'); const alertMsg = document.querySelector('.msg-alerte'); // 监听表单的submit事件,比监听按钮click更可靠 form.addEventListener('submit', (e) => { // 阻止表单默认提交行为,避免页面刷新 e.preventDefault(); // 获取并清洗用户输入 const username = usernameInput.value.trim(); const email = emailInput.value.trim(); const password = passwordInput.value.trim(); // 前端简单校验 if (!username || !email || !password) { alertMsg.textContent = '请填写所有必填字段'; return; } fetch('/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ user_name: username, email: email, password: password }) }) .then(res => { if (!res.ok) throw new Error('请求失败'); return res.json(); }) .then(() => { alertMsg.textContent = '注册成功!'; // 跳转到登录页 window.location.href = '/connexion.html'; }) .catch(err => { console.error('注册失败:', err); alertMsg.textContent = '注册失败,请稍后重试'; }); });
后端代码问题与修复
- 未解析JSON请求体
- Express默认不会解析JSON格式的请求体,必须添加
express.json()中间件,否则req.body会是undefined。
- Express默认不会解析JSON格式的请求体,必须添加
- SQL查询参数错误
- 你的SQL语句有3个占位符
?,但传入的是[data](一个对象),应该传对应字段的数组。
- 你的SQL语句有3个占位符
- 密码明文存储风险
- 绝对不能将密码明文存入数据库,必须用bcrypt等工具加密后再存储。
修复后的后端Node.js代码(需提前安装bcrypt):
const express = require('express'); const bcrypt = require('bcrypt'); const app = express(); // 必须在路由前添加JSON解析中间件 app.use(express.json()); // 如需处理传统表单的urlencoded格式,可添加此中间件 app.use(express.urlencoded({ extended: true })); app.post("/", async (req, resp) => { try { const { user_name, email, password } = req.body; // 后端校验必填字段 if (!user_name || !email || !password) { return resp.status(400).json({ message: '缺少必填字段' }); } // 加密密码,盐值rounds推荐设为10及以上 const hashedPassword = await bcrypt.hash(password, 10); const sql = "INSERT INTO users (user_name, email, password) VALUES (?, ?, ?);"; // 传入对应字段的数组,而非整个对象 await pool.query(sql, [user_name, email, hashedPassword]); console.log("Enregistrement effectuee"); resp.status(200).json({ message: '注册成功' }); } catch (err) { console.error("Echec d'enregistrement à BD:", err); resp.status(500).json({ message: '服务器内部错误' }); } });
额外注意事项
- HTML里的form标签可以去掉
action和method属性,因为我们已经用fetch处理了提交逻辑。 - 确保数据库
users表的字段名(user_name、email、password)与代码中的字段名完全一致。 - 安装所需依赖:
npm install express bcrypt mysql2(假设你用mysql2连接数据库)
内容的提问来源于stack exchange,提问作者Anais
相关产品推荐
相关产品推荐

