无法从HTML表单向Node.js服务器传数据,报400错误求助
注册接口POST请求400错误排查与修复
问题描述
点击注册按钮后,浏览器控制台返回POST http://127.0.0.1:3000/user/register 400 (Bad Request),服务器运行正常但数据传递存在异常,相关代码如下:
带JavaScript事件监听器的HTML表单
<title>Register</title> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!--===============================================================================================--> <link rel="icon" type="image/png" href="../assets/images/icons/favicon.ico"/> <!--===============================================================================================--> <link rel="stylesheet" type="text/css" href="../assets/vendor/bootstrap/css/bootstrap.min.css"> <!--===============================================================================================--> <link rel="stylesheet" type="text/css" href="../assets/fonts/font-awesome-4.7.0/css/font-awesome.min.css"> <!--===============================================================================================--> <link rel="stylesheet" type="text/css" href="../assets/vendor/animate/animate.css"> <!--===============================================================================================--> <link rel="stylesheet" type="text/css" href="../assets/vendor/css-hamburgers/hamburgers.min.css"> <!--===============================================================================================--> <link rel="stylesheet" type="text/css" href="../assets/vendor/select2/select2.min.css"> <!--===============================================================================================--> <link rel="stylesheet" type="text/css" href="../assets/css/util.css"> <link rel="stylesheet" type="text/css" href="../assets/css/main.css"> <!--===============================================================================================--> </head> <body> <div class="limiter"> <div class="container-login100"> <div class="wrap-login100"> <div class="login100-pic js-tilt" data-tilt> <img src="../assets/images/img-01.png" alt="IMG"> </div> <form class="login100-form validate-form"> <span class="login100-form-title"> Register </span> <div class="wrap-input100 validate-input" data-validate = "Valid username is required!!!"> <input class="input100" type="text" name="user" placeholder="Username"> <span class="focus-input100"></span> <span class="symbol-input100"> <i class="fa fa-user" aria-hidden="true"></i> </span> </div> <div class="wrap-input100 validate-input" data-validate = "Valid email is required!!!"> <input class="input100" type="text" name="email" placeholder="Email"> <span class="focus-input100"></span> <span class="symbol-input100"> <i class="fa fa-envelope" aria-hidden="true"></i> </span> </div> <div class="wrap-input100 validate-input" data-validate = "Password is required"> <input class="input100" type="password" name="pass1" placeholder="Enter Password"> <span class="focus-input100"></span> <span class="symbol-input100"> <i class="fa fa-lock" aria-hidden="true"></i> </span> </div> <div class="wrap-input100 validate-input" data-validate = "Valid password is required!!!"> <input class="input100" type="password" name="pass2" placeholder="Confirm Password"> <span class="focus-input100"></span> <span class="symbol-input100"> <i class="fa fa-lock" aria-hidden="true"></i> </span> </div> <div class="username error"> </div> <div class="email error"> </div> <div class="password error"> </div> <div class="container-login100-form-btn"> <button name="submit" class="login100-form-btn"> Register </button> </div> <div class="text-center p-t-12"> <span class="txt1"> Have an account? </span> <a class="txt2" href="/user/login"> Login </a> </div> </form> </div> </div> </div> <!--===============================================================================================--> <script src="../assets/vendor/jquery/jquery-3.2.1.min.js"></script> <!--===============================================================================================--> <script src="../assets/vendor/bootstrap/js/popper.js"></script> <script src="../assets/vendor/bootstrap/js/bootstrap.min.js"></script> <!--===============================================================================================--> <script src="../assets/vendor/select2/select2.min.js"></script> <!--===============================================================================================--> <script src="../assets/vendor/tilt/tilt.jquery.min.js"></script> <script> $('.js-tilt').tilt({ scale: 1.1 }) </script> <!--===============================================================================================--> <script src="../assets/js/main.js"></script> <script> const form = document.querySelector('form'); form.addEventListener('submit', async (e) => { e.preventDefault(); const username = form.user.value; const email = form.email.value; const password = form .pass1.value; try { const result = await fetch('/user/register', { method: 'POST', body: JSON.stringify({ username, email, password }), headers: { 'Content-Type': 'application/json' } }); } catch (err) { console.log(err); } }) </script> </body> </html>
注册接口Controller代码
const register_get = (req, res) => { res.render('register') } const register_post = async (req, res) => { const { username, email, password } = req.body; try { const user = await User.create({ username, email, password }); res.status(201).json({ errors }); } catch (err) { const errors = handleErrors(err); res.status(400).json({ errors }); } }
错误处理函数
const handleErrors = (err) => { let errors = { username: '', email: '', password: '' } if (err.code === 11000) { errors.email = 'Email has been registered already. Kindly Login in!'; return errors; } if(err.message.includes('user validation failed')) { Object.values(err.errors).ForEach(({ properties }) => { errors[properties.path] = properties.message; }); } return errors; }
问题排查与修复
1. Controller成功响应时变量未定义
在register_post的try块中,res.status(201).json({ errors });里的errors未定义,会触发引用错误并进入catch块返回400。修复如下:
const register_post = async (req, res) => { const { username, email, password } = req.body; try { const user = await User.create({ username, email, password }); // 返回成功信息,替换未定义的errors res.status(201).json({ message: '注册成功', userId: user._id }); } catch (err) { const errors = handleErrors(err); res.status(400).json({ errors }); } }
2. 错误处理函数方法拼写错误
Object.values(err.errors).ForEach中的ForEach应为小写开头的forEach,JavaScript数组方法区分大小写,拼写错误会导致方法不存在并抛出异常。修复如下:
const handleErrors = (err) => { let errors = { username: '', email: '', password: '' } if (err.code === 11000) { errors.email = '该邮箱已注册,请直接登录!'; return errors; } if(err.message.includes('user validation failed')) { // 修正forEach拼写 Object.values(err.errors).forEach(({ properties }) => { errors[properties.path] = properties.message; }); } return errors; }
3. 前端未验证两次密码一致性
HTML表单包含两次密码输入框,但前端未校验pass1和pass2是否一致,可能导致无效数据提交。同时需添加fetch响应状态检查(fetch仅在网络错误时触发catch,HTTP错误需手动判断)。修复后的前端JS:
const form = document.querySelector('form'); form.addEventListener('submit', async (e) => { e.preventDefault(); const username = form.user.value; const email = form.email.value; const password = form.pass1.value; const confirmPassword = form.pass2.value; // 清空之前的错误提示 document.querySelectorAll('.error').forEach(el => el.textContent = ''); // 验证两次密码一致 if (password !== confirmPassword) { document.querySelector('.password.error').textContent = '两次输入的密码不一致'; return; } try { const result = await fetch('/user/register', { method: 'POST', body: JSON.stringify({ username, email, password }), headers: { 'Content-Type': 'application/json' } }); // 检查HTTP响应状态 if (!result.ok) { const errorData = await result.json(); // 将错误信息显示到对应元素 if (errorData.errors.username) { document.querySelector('.username.error').textContent = errorData.errors.username; } if (errorData.errors.email) { document.querySelector('.email.error').textContent = errorData.errors.email; } if (errorData.errors.password) { document.querySelector('.password.error').textContent = errorData.errors.password; } return; } // 注册成功后跳转到登录页 window.location.href = '/user/login'; } catch (err) { console.log(err); } })
4. 额外注意项
- 确保后端已配置
express.json()中间件,否则无法解析JSON格式的请求体; - 检查MongoDB的User Schema是否包含
username、email、password字段的验证规则,验证失败也会触发400错误。
内容的提问来源于stack exchange,提问作者Bright
相关产品推荐
相关产品推荐

