Вопрос или проблема
Я пытаюсь отправить вложение на конечную точку 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" });
});
});
Объяснения изменений:
-
Проверка
userID
перед выполнением запроса: Теперь перенесена проверкаreq.session.userID
до того, как будет сделан запрос. ЕслиuserID
не установлен, выполнение функции завершится с помощьюreturn
, предотвращая дальнейшие действия послеres.redirect()
. -
Использование
return
в обработчике ошибок: Если происходит ошибка, теперь использованиеreturn
дляres.send
гарантирует, что выполнение не продолжится после отправки ответа.
Эти изменения помогут предотвратить отправку нескольких ответов и, соответственно, исправить ошибку ERR_HTTP_HEADERS_SENT
.