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

Node.js项目添加认证时出现Error [ERR_HTTP_HEADERS_SENT]错误的解决求助

Node.js项目添加认证时出现Error [ERR_HTTP_HEADERS_SENT]错误的解决求助

Hey there! Let's dig into why you're running into this Error [ERR_HTTP_HEADERS_SENT] issue. I've gone through your code and the root cause is pretty clear—you're accidentally sending multiple HTTP responses to the client, which Node.js blocks to prevent inconsistent behavior.

What's Causing the Error?

The core problem lies in your authUser middleware:

  • Whenever there's an authentication failure (invalid token, missing user, no token present), you send an error response with res.status().json(), but you still call next() afterwards.
  • This means even after telling the client "invalid token", you're letting the request proceed to your fetchOne controller, which then tries to send another response (either the data or a 404). Sending two responses to the same request triggers the ERR_HTTP_HEADERS_SENT error.

Fix #1: Correct the Authentication Middleware

You need to ensure that only successful authentication triggers next(), and you stop execution immediately after sending an error response. Here's the fixed middleware:

const authUser = (req, res, next) => {
  console.log("Auth middleware");
  if (req.headers && req.headers.authorization && req.headers.authorization.split(" ")[0] === "JWT") {
    jwt.verify(
      req.headers.authorization.split(" ")[1],
      process.env.JWT_SECRET,
      function (err, verifyToken) {
        if (err) {
          // Send error response and stop further execution
          return res.status(401).json({ message: "Invalid JWT Token" });
        }
        userModel
          .findById(verifyToken.id)
          .then((user) => {
            if (!user) {
              return res.status(401).json({ message: "Invalid User" });
            }
            // Optional: Attach user to request for use in controllers
            req.user = user;
            // Only call next() if authentication succeeds
            next();
          })
          .catch((err) => {
            return res.status(500).json({ message: err.message || "Server Error" });
          });
      }
    );
  } else {
    // Send error and stop execution
    return res.status(403).json({ message: "Token not present" });
  }
};

Key changes here:

  • Added return after every error response to halt the middleware function.
  • Moved next() inside the successful user lookup block—only called when authentication is fully valid.

Fix #2: Improve Your Controller's Error Handling

Your fetchOne controller has a small issue too: the try/catch won't catch errors from the findById().then() Promise chain because it's asynchronous. Let's fix that either with proper Promise error handling or async/await:

Option A: Promise Chain with Proper Error Handling

exports.fetchOne = (req, res) => {
  const _id = req.params.id;
  console.log("fetch One");

  collectionsModel.findById(_id)
    .then((data) => {
      if (!data) {
        return res.status(404).json({ message: "Data not found" });
      }
      console.log(data);
      res.send(data);
    })
    .catch((error) => {
      console.log(error.message);
      // Send error response to client instead of just logging
      res.status(500).json({ message: error.message || "Failed to fetch data" });
    });
};

Option B: Async/Await with Try/Catch

exports.fetchOne = async (req, res) => {
  const _id = req.params.id;
  console.log("fetch One");

  try {
    const data = await collectionsModel.findById(_id);
    if (!data) {
      return res.status(404).json({ message: "Data not found" });
    }
    console.log(data);
    res.send(data);
  } catch (error) {
    console.log(error.message);
    res.status(500).json({ message: error.message || "Failed to fetch data" });
  }
};

Why This Works

  • The middleware now only passes valid requests to the controller, so you never get duplicate responses.
  • The controller ensures exactly one response is sent per request, whether it's the requested data, a 404, or a server error.

Give these changes a try—your authentication should work correctly, and the ERR_HTTP_HEADERS_SENT error should disappear!

备注:内容来源于stack exchange,提问作者GOKULNATH RS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 07:58:06