简体   繁体   中英

ExpressJS - Unhandled rejection Error: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I am able to register and login to the application but I receive the following server error:

"Unhandled rejection Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client" upon registration. I came across similar questions here but none of them resolved my problem.

authController.js:

const User = require("../models/User");
const jwt = require("jsonwebtoken");
const simplecrypt = require("simplecrypt");
const sc = simplecrypt();

process.env.SECRET_KEY = "secret";

exports.postLogin = (req, res, next) => {
  const { username, password } = req.body;
  let validationMessages = [];

  if (!username || !password) {
    validationMessages.push({ message: "Please fill in all fields" });
  }

  if (password.length < 6) {
    validationMessages.push({
      message: "Password should be at least 6 characters"
    });
  }

  if (validationMessages.length > 0) {
    res.sendStatus(403).json(validationMessages);
  } else {
    User.findOne({ where: { username: username } })
      .then(user => {
        if (!user) {
          res.sendStatus(400).json({
            message: "Invalid username or password"
          });
        } else if (password == sc.decrypt(user.password)) {
          const token = jwt.sign(user.dataValues, process.env.SECRET_KEY, {
            expiresIn: 1440 // expires in 24 hours
          });
          res.send(token);
        }
      })
      .catch(err => {
        res.send("Error: " + err);
      });
  }
};

exports.postRegister = (req, res, next) => {
  const { username, password, password2 } = req.body;
  let validationMessages = [];

  //Check required fields
  if (!username || !password || !password2) {
    validationMessages.push({ message: "Please fill in all fields" });
  }

  if (password.length < 6 || password2.length < 6) {
    validationMessages.push({
      message: "Password should be at least 6 characters"
    });
  }

  if (password !== password2) {
    validationMessages.push({
      message: "Passwords do not match"
    });
  }

  if (validationMessages.length > 0) {
    return res.sendStatus(400).json(validationMessages);
  } else {
    User.findOne({ where: { username: username } })
      .then(user => {
        if (user) {
          return res.sendStatus(403).json("User already exists");
        }
        const hashedPassword = sc.encrypt(password);
        User.create({ username: username, password: hashedPassword })
          .then(user => {
            return res.sendStatus(200).send(user);
          })
          .catch(err => {
            throw new Error(err);
          });
      })
      .catch(err => {
        throw new Error(err);
      });
  }
};

exports.getProfile = (req, res, next) => {
  const decoded = jwt.verify(
    req.headers["authorization"],
    process.env.SECRET_KEY
  );
  User.findOne({
    where: {
      id: decoded.id
    }
  })
    .then(user => {
      if (user) {
        res.statusCode(200).json(user);
      } else {
        throw new Error("User does not exist");
      }
    })
    .catch(err => {
      throw new Error(err);
    });
};

I am using Node.JS v12.14.0 and Express.JS v4.17.1 .

I resolved it myself. My problem was using res.sendStatus which sets the given response HTTP status code and sends its string representation as the response body. res.json will set the content-type response header, but at time time the response will already have been sent to the client. So simply res.send() should replace res.sendStatus().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM