You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
      })
  );
}

问题原因及解决方法

  1. 重复发送响应导致头错误
    你的错误处理代码res.json("Incorrect Email.").sendStatus(401)存在逻辑错误:res.json()会自动发送一个状态码为200的响应,之后调用sendStatus(401)会尝试再次修改响应头,这就触发了ERR_HTTP_HEADERS_SENT错误。

  2. 正确的响应写法
    只需二选一即可:

    • 要返回错误信息+401状态:return res.status(401).json("邮箱不正确")
    • 仅返回401状态无内容:return res.sendStatus(401)
  3. 关于Objection.js的误解
    Objection.js不会自动发送任何响应,问题完全出在你的响应处理代码上。错误调用两次响应方法时,第一次发送了200状态的响应,第二次的操作无效,所以前端收到的始终是200。

  4. 额外注意事项

    • 处理完错误分支后,一定要加return终止后续代码执行,避免后续还有其他响应逻辑导致重复发送。
    • 前端401分支的错误提示建议和后端返回内容保持一致,提升用户体验。

内容的提问来源于stack exchange,提问作者user19156619

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:20:27