Objection.js是否自动返回200响应?登录接口报错求助
登录接口迁移到Objection.js/Knex后出现响应头错误及状态码异常问题
问题详情
之前使用MongoDB,迁移到Objection.js和Knex后,后端登录接口出现异常。后端相关代码片段:
User.query() .where("email", "=", req.body.email) .then((user) => { if (user.length == 0) { return res.json("Incorrect Email.").sendStatus(401); // 邮箱未注册时的处理逻辑 }
当前遇到两个问题:
- 后端报错:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client - 前端收到的响应状态码始终是200,即使邮箱输入错误
补充前端登录请求代码
async function handleSubmit(e) { e.preventDefault(); await fetch(`https://localhost:8443/api/auth/login`, { method: "POST", mode: "cors", credentials: "include", headers: { Accept: "application/json", "Content-Type": "application/json", }, body: JSON.stringify({ email, password }), }).then((response) => response .json() .then(({ data }) => { console.log(response); switch (response.status) { case 200: localStorage.setItem("xsrfToken", JSON.stringify(data.xsrfToken)); const roles = data.roles; const _id = data._id; const accessToken = data.accessToken; setAuth({ _id, email, password, roles, accessToken }); setEmail(""); setPassword(""); // 部署前删除该日志 console.log(data); navigate(from, { replace: true }); break; case 401: setErrMsg("邮箱或密码错误"); errRef.current.focus(); // 部署前删除该日志 console.log(data); break; case 500: setErrMsg("服务器内部错误"); console.log(data); break; default: } }) .catch((error) => { errRef.current.focus(); console.log(error); }) ); }
问题原因及解决方法
重复发送响应导致头错误
你的错误处理代码res.json("Incorrect Email.").sendStatus(401)存在逻辑错误:res.json()会自动发送一个状态码为200的响应,之后调用sendStatus(401)会尝试再次修改响应头,这就触发了ERR_HTTP_HEADERS_SENT错误。正确的响应写法
只需二选一即可:- 要返回错误信息+401状态:
return res.status(401).json("邮箱不正确") - 仅返回401状态无内容:
return res.sendStatus(401)
- 要返回错误信息+401状态:
关于Objection.js的误解
Objection.js不会自动发送任何响应,问题完全出在你的响应处理代码上。错误调用两次响应方法时,第一次发送了200状态的响应,第二次的操作无效,所以前端收到的始终是200。额外注意事项
- 处理完错误分支后,一定要加
return终止后续代码执行,避免后续还有其他响应逻辑导致重复发送。 - 前端401分支的错误提示建议和后端返回内容保持一致,提升用户体验。
- 处理完错误分支后,一定要加
内容的提问来源于stack exchange,提问作者user19156619
相关产品推荐
相关产品推荐

