【问题标题】:New Mongoose Schema `ERR_HTTP_HEADERS_SENT` erorr in Express.jsExpress.js 中的新 Mongoose Schema `ERR_HTTP_HEADERS_SENT` 错误
【发布时间】:2021-09-09 10:52:27
【问题描述】:

我的目标是

如果找到任何数据 findOne() 函数使用内容更新当前端点,如果没有使用 Schema 创建新元素。

问题

如果 db 中没有数据,那么首先if 它会将ERR_HTTP_HEADERS_SENT 与console.log = 1 相结合,但如果有,则使用console.log = 3 一切正常。

  try {
    const find = await endPointSchema.findOne({ uuid: uuid });
    if (!find) {
      const data = new endPointSchema({
        uuid: uuid,
        endpoint: [{ point: Endpoint, Content }],
        date: Date.now(),
      });
      await data.save();
      console.log(1);
      res.status(200).json({ message: "Succesfully Created new Breakpoint" });
      return;
    } else {
      if (!find.endpoint) {
        console.log(2);
        res.end();
        return;
      } else {
        console.log(3);
        res.end();
        return;
      }
    }
  } catch (e) {
    console.log(e);
    res.end();
    return;
  }

我的端点

route.post("/endpoint", AuthorizePanel, async (req, res) => {
  const { role, username, uuid } = req.user;
  if (!role && !username && !uuid) {
    res.sendStatus(401);
    return;
  }

  const { Endpoint, Content } = req.body;
  if (Endpoint === username) {
    res.status(403).json({ message: "Endpoint can not be same with your username!" });
    return;
  }

  try {
    const find = await endPointSchema.findOne({ uuid: uuid });
    if (!find) {
      const data = new endPointSchema({
        uuid: uuid,
        endpoint: [{ point: Endpoint, Content }],
        date: Date.now(),
      });
      await data.save();
      console.log(1);
      res.status(200).json({ message: "Succesfully Created new Breakpoint" });
      return;
    } else {
      if (!find.endpoint) {
        console.log(2);
        res.end();
        return;
      } else {
        console.log(3);
        res.end();
        return;
      }
    }
  } catch (e) {
    console.log(e);
    res.end();
    return;
  }
});

授权面板


import jwt from "jsonwebtoken";

export const AuthorizePanel = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    const token = authHeader.split(" ")[1];
    jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
      if (err) {
        res.sendStatus(403)
        return
      }
      req.user = user;
      next();
    });
  }
  next();
};

【问题讨论】:

  • 1 在不成功的流程中打印?数据是否保存?
  • 是的,我知道这很有趣,但是在 http 标头错误之后我看到它已保存。
  • 该错误通常是当您在发送一个响应后发送 res 时。查看您的代码,我不明白这是怎么回事。您可以在使用 res 的地方添加/检查更多代码流吗?
  • 就像我无法理解的那样
  • 可能在此函数之前的某个地方还有另一个 res.end() 或 res.send()。

标签: javascript node.js express mongoose nosql


【解决方案1】:

问题在于 auth 中间件,如果您仔细查看 auth 中间件,您会注意到 jwt.verify 函数中的 return 语句仅针对该函数返回。 jwt.verify 函数执行后,next(); 函数也可以工作。要打断你需要在你的第一个 if 块中添加 else 块

export const AuthorizePanel = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    const token = authHeader.split(" ")[1];
    jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
      if (err) {
        res.sendStatus(403)
        return
      }
      req.user = user;
      next();
    });
  } else {
    next();
  }

};

【讨论】:

    【解决方案2】:

    在 authorizePanel 中,将第二个 next 放在 else 条件中或将其删除(如果您只希望经过身份验证的用户继续前进)。 每次都会调用它。

    为什么我认为有错误

    为了简化,让我们用 mongoose call function A来调用函数。

    您的 JWT 验证代码中有一个回调,因此将在将来某个时间点异步调用它。

    如果用户遇到身份验证错误,则请求将尝试返回响应(异步)并调用函数 A(立即因为 if 外部的 next())将发送自己的响应。 此外,如果没有错误,则流程也将转移到功能 A。 (注意因为if条件之外的另一个next(),所以流程已经移到A了)。

    在任何一种情况下,您的服务器都可能发送 2 个响应。一个带有 JWT 错误和您的第二个 函数 A。或者两者都来自您的函数 A

    可能会保存数据,但之后会出现错误,因为标头已发送,服务器正在尝试再次执行此操作。

    【讨论】:

    • 正如我所说,我使用了这个中间件功能,但我从未收到此错误。我认为问题出在端点功能上,所以您会问我如何确定这一点,因为当我替换此功能时,另一个功能不会出现此错误。
    • 你的其他函数是否也发送响应?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 2021-03-27
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多