throw new ERR_HTTP_HEADERS_SENT(‘set’); ^ Ошибка [ERR_HTTP_HEADERS_SENT]: Невозможно установить заголовки после того, как они были отправлены клиенту.

Вопрос или проблема

Я пытаюсь отправить вложение на конечную точку API UploadFxPLink, но постоянно получаю следующую ошибку:

Error [ERR_HTTP_HEADERS_SENT]: Невозможно установить заголовки после их отправки клиенту
    at new NodeError (node:internal/errors:399:5)
    at ServerResponse.setHeader (node:_http_outgoing:645:11)
    at ServerResponse.header (D:\NIDC\BL1\node_modules\express\lib\response.js:771:10)
    at ServerResponse.send (D:\NIDC\BL1\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (D:\NIDC\BL1\node_modules\express\lib\response.js:267:15)
    at ServerResponse.send (D:\NIDC\BL1\node_modules\express\lib\response.js:158:21)
    at Request._callback (D:\NIDC\BL1\ors.js:2848:11)
    at self.callback (D:\NIDC\BL1\node_modules\request\request.js:185:22)
    at Request.emit (node:events:513:28)
    at Request.onRequestError (D:\NIDC\BL1\node_modules\request\request.js:877:8) {
  code: 'ERR_HTTP_HEADERS_SENT'
}

Я понимаю, что эта ошибка обычно означает, что заголовки (такие как код состояния или тип контента) устанавливаются после того, как ответ уже был отправлен, но я проверил свой код и убедился, что возвращаю ответ для каждого пути.

Вот соответствующий код:

app.post('/UploadFxP', function (req, res) {
  var trackngNo = req.session.TrackingNo;
  var attachmentId = req.body.attachmentId;
  var trackNo = req.body.trackNo;
  var userId = req.session.userID;
  var token = req.session.token;
  var atachment = req.body.atachment;
  var attachment = atachment.replace("data:application/pdf;base64,", "");

  console.log('trackingNo: ', trackngNo)
  if (req.session.userID) {
    request({
      url: UploadFxPLink,
      method: 'POST',
      json: {
        trackNo: trackNo,
        trackngNo: trackngNo,
        userId: userId,
        attachmentId: attachmentId,
        atachment: attachment,
        token: token
      },
      headers: {
        'Authorization': `Bearer ${token}`
      }
    }, function (error, response, body) {
      if (error) {
        console.log("Не удалось загрузить UploadFxP " + error);
        return res.send({ "failed": "failed" });  // добавлен возврат здесь
      }

      return res.send({ "success": "success" });  // добавлен возврат здесь
    });
  } else {
    res.redirect("https://stackoverflow.com/");
  }
});

Ответ или решение

Ошибка ERR_HTTP_HEADERS_SENT указывает на то, что вы пытаетесь установить заголовки HTTP после того, как ответ уже был отправлен клиенту. Это распространенная проблема в Node.js и Express, когда в коде есть несколько точек, из которых может быть отправлен ответ, что приводит к попытке несколько раз отправить заголовки.

В вашем коде, основная проблема заключается в том, что вы не возвращаете (или не завершаете) обработку, после того как вызываете res.redirect() в ветке else. Если req.session.userID не установлен, будет выполнен res.redirect("https://stackoverflow.com/"), и после этого выполнение продолжится, что также попытается отправить ответ (например, если запрос обработан успешно или произошла ошибка).

Вот как вы можете улучшить код:

app.post('/UploadFxP', function (req, res) {
  const trackngNo = req.session.TrackingNo;
  const attachmentId = req.body.attachmentId;
  const trackNo = req.body.trackNo;
  const userId = req.session.userID;
  const token = req.session.token;
  const atachment = req.body.atachment;
  const attachment = atachment.replace("data:application/pdf;base64,", "");

  console.log('trackingNo: ', trackngNo);

  // Проверяем, установлен ли userID
  if (!req.session.userID) {
    return res.redirect("https://stackoverflow.com/");
  }

  request({
    url: UploadFxPLink,
    method: 'POST',
    json: {
      trackNo: trackNo,
      trackngNo: trackngNo,
      userId: userId,
      attachmentId: attachmentId,
      atachment: attachment,
      token: token
    },
    headers: {
      'Authorization': `Bearer ${token}`
    }
  }, function (error, response, body) {
    if (error) {
      console.log("Failed to UploadFxP " + error);
      return res.send({ "failed": "failed" });  // Возвращаем здесь, чтобы остановить исполнение
    }

    // Возвращаем успешный ответ
    return res.send({ "success": "success" });
  });
});

Объяснения изменений:

  1. Проверка userID перед выполнением запроса: Теперь перенесена проверка req.session.userID до того, как будет сделан запрос. Если userID не установлен, выполнение функции завершится с помощью return, предотвращая дальнейшие действия после res.redirect().

  2. Использование return в обработчике ошибок: Если происходит ошибка, теперь использование return для res.send гарантирует, что выполнение не продолжится после отправки ответа.

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

Оцените материал
Добавить комментарий

Капча загружается...