Node.js注册表单触发UnhandledPromiseRejectionWarning错误求解决示例
问题根因
- 核心错误1:
ERR_HTTP_HEADERS_SENT触发原因是你在用户名/邮箱重复时执行res.redirect后,只终止了当前then回调的执行,没有阻止后续代码继续运行,后续逻辑还会再次调用res.redirect("/home"),相当于单次请求多次返回响应,触发响应头重复设置错误。 - 核心错误2:混用
await、then回调、普通回调三种异步处理逻辑,没有统一错误捕获,导致Promise rejection没有被处理,触发未处理Promise拒绝的警告。 - 细节错误:
bcrypt.hashSync是同步方法,不需要加await;user.save同时用了await和回调函数,逻辑冲突;缺少密码一致性校验逻辑、参数缺失的兜底返回逻辑。
修复后参考代码
// 需确保当前路由处理函数被async修饰,示例:app.post('/register', async (req, res, next) => { if (req.body.email_reg && req.body.name_reg && req.body.user_reg && req.body.password_reg && req.body.password_conf_reg) { try { const { user_reg, name_reg, email_reg, password_reg, password_conf_reg } = req.body; // 校验两次密码是否一致 if (password_reg !== password_conf_reg) { req.session.error = "两次输入的密码不一致,请检查"; return res.redirect("/"); } // 并行查询用户名和邮箱是否存在,提升执行效率 const [existUser, existEmail] = await Promise.all([ User.findOne({ user: user_reg }), User.findOne({ email: email_reg }) ]); if (existUser) { req.session.error = "用户名已被占用,请检查"; return res.redirect("/"); } if (existEmail) { req.session.error = "邮箱已被占用,请检查"; return res.redirect("/"); } // 同步hash方法不需要加await const hasdPsw = bcrypt.hashSync(password_reg, 12); const user = new User({ user: user_reg, name: name_reg, email: email_reg, password: hasdPsw, permission:'user' }); // 统一用await处理保存操作,不混用回调 await user.save(); req.session.isAuth = true; req.session.user = user.user; return res.redirect("/home"); } catch (err) { // 统一捕获所有异步错误 const error = new Error('用户保存失败,请检查'); error.status = 400; return next(error); } } else { // 兜底处理参数缺失的场景 req.session.error = "请完善所有注册必填项"; return res.redirect("/"); } // })
内容的提问来源于stack exchange,提问作者Luca Serafini
相关产品推荐
相关产品推荐

