ERR_HTTP_HEADERS_SENT: невозможно установить заголовки после их отправки клиенту - PullRequest
0 голосов
/ 31 августа 2018

Я сталкиваюсь с этой странной проблемой в NodeJS при использовании с Passport.js, Express и Mongoose. Обычно я получаю сообщение об ошибке «Невозможно установить заголовки после их отправки клиенту», даже если я не отправляю более одного заголовка.

Я прочитал и другие посты и попробовал их, но ни один из них не сработал.

Я копался в проблемах с github и не могу найти решение. У меня проблема в том, что эта ошибка возникает при отправке нескольких заголовков ответа, но дело в том, что я не отправляю несколько заголовков. Это кажется странным.

Это моя трассировка стека:

(узел: 9236) DeprecationWarning: текущий синтаксический анализатор строки URL устарел и будет удален в следующей версии. Чтобы использовать новый анализатор, передайте параметр {useNewUrlParser: true} в MongoClient.connect.

Сервер, работающий на порту 5000
Ошибка подключения MongoDB
[ERR_HTTP_HEADERS_SENT]: Невозможно установить заголовки после их отправки в клиент
at validateHeader (_http_outgoing.js: 503: 11)
в ServerResponse.setHeader (_http_outgoing.js: 510: 3)
на ServerResponse.header (/Users/lourdesroashan/code/github/devlog/node_modules/express/lib/response.js:767:10)
на сервере ServerResponse.json (/Users/lourdesroashan/code/github/devlog/node_modules/express/lib/response.js:264:10)
в Profile.findOne.then.profile (/Users/lourdesroashan/code/github/devlog/routes/api/profile.js:27:30)
в

Это мой код сервера:

router.get("/userprofile", passport.authenticate('jwt', { session: false }), (req, res) => {

  Profile.findOne({ user: req.user.id }).then(profile => {
    if (!profile) {
      return res.status(404).json({ error: "No Profile Found" });
    }
    else {
      res.json(profile);
    }
  }).catch(err => {
    console.log(err);
  })
});

Я понимаю, что означает ошибка, но из того, что я знаю, я не думаю, что посылаю несколько заголовков, я даже проверил в console.log, что выполняется только один из блоков.

Заранее большое спасибо! :)

Полный код по адресу: https://github.com/lourdesr/devlog

EDIT:

Я понял это. Это была проблема в моем passport.js при попытке получить аутентифицированного пользователя. Я забыл использовать return для метода done, вызвавшего его. Просто добавил оператор возврата и все заработало!

Ответы [ 3 ]

0 голосов
/ 09 мая 2019

Извините за поздний ответ, Согласно документации mongoose, «запросы Mongoose не являются обещаниями. Для удобства они имеют функцию .then () для co и async / await. Однако, в отличие от обещаний, вызов .then () для запроса может выполнять запрос несколько раз»

чтобы использовать обещания

mongoose.Promise = global.Promise //To use the native js promises

Тогда

var promise = Profile.findOne({ user: req.user.id }).exec()
promise.then(function (profile){
    if (!profile) {
      throw new Error("User profile not found") //reject promise with error
    }
    return res.status(200).json(profile) //return user profile      
}).catch(function (err){
    console.log(err); //User profile not found
    return res.status(404).json({ err.message }) //return your error msg
})

вот хорошая статья о переключении обратных вызовов с обещаниями в Mongoose

и этот ответ об обработке отклонения обещания мангустов Обработка отклонения обещания Мангуста

0 голосов
/ 05 августа 2019

Я получал эту ошибку из-за глупой ошибки с моей стороны. Мне нужно быть более осторожным, ссылаясь на другой мой рабочий код. Действительно смущающая часть - то, как долго я потратил, пытаясь выяснить причину ошибки. Ouf!

Bad:

return res
  .send(C.Status.OK)
  .json({ item });

Хорошо:

return res
  .status(C.Status.OK)
  .json({ item });
0 голосов
/ 31 августа 2018

Эта конкретная ошибка возникает всякий раз, когда вы пытаетесь отправить более одного ответа на один и тот же запрос, и обычно вызывается неправильным асинхронным кодом.

Код, который вы показываете в своем вопросе, не выглядит так, как будто он вызывает эту ошибку, но я вижу код на другом маршруте здесь , который может вызвать эту ошибку.

Где у вас это:

if (!user) {
  errors.email = "User not found";
  res.status(404).json({ errors });
}

Вам нужно изменить его на:

if (!user) {
  errors.email = "User not found";
  res.status(404).json({ errors });
  // stop further execution in this callback
  return;
}

Вы не хотите, чтобы код продолжался после того, как вы сделали res.status(404).json({ errors });, потому что тогда он попытается отправить другой ответ.


Кроме того, везде у вас есть это:

if (err) throw err;

внутри асинхронного обратного вызова, вам нужно заменить это на что-то, что на самом деле отправляет ответ об ошибке, такой как:

if (err) {
    console.log(err);
    res.sendStatus(500);
    return;
}

Бросок внутри асинхронного обратного вызова просто возвращается в систему событий node.js и не выбрасывается никуда, где вы можете его поймать. Кроме того, он не отправляет ответ на запрос http. Другими словами, он на самом деле не делает то, что должен делать сервер. Поэтому сделайте себе одолжение и никогда не пишите этот код на своем сервере. Если вы получили сообщение об ошибке, отправьте ответ об ошибке.


Поскольку, похоже, вы здесь новичок, я хотел бы поблагодарить вас за добавление ссылки на ваш полный исходный код по адресу https://github.com/lourdesr/devlog, потому что только увидев это, я смог увидеть это место, где ошибка происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...