#mongodb #express #express-router
#mongodb — монгодб #выражать #express-router #mongodb #экспресс #экспресс-маршрутизатор
Вопрос:
Я получаю ошибку [ERR_HTTP_HEADERS_SENT]: Не удается установить заголовки после их отправки клиенту, а затем какой-то длинный список с указанием местоположения ошибок при выполнении запроса POST является экспресс-маршрутом. Я видел похожие ответы, получил много, но не смог уловить, чего мне не хватает.
Здесь я прилагаю пример кода этого конкретного запроса POST.
.post(cors.corsWithOptions, authenticate.verifyUser, (req, res, next) => {
Favorites.findOne({user: req.user._id})
.then((favs)=> {
if(!favs) {
Favorites.create({user: req.user._id, dishes: req.body})
.then((favs)=> {
console.log('Favs created: ', favs);
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(favs);
}, (err) => next(err))
.catch((err) => next(err));
}
else {
var noofids = req.body.length;
for (var i=0; i<noofids ; i ) {
if(favs.dishes.indexOf(req.body[i]._id) > -1) {
res.json('It is already in the dishes');
}
else {
favs.dishes.push(req.body[i]._id);
favs.save()
.then((doc) => {
Favorites.findById(doc._id)
.populate('User').populate('Dishes')
.then((fav) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(fav);
}, (err) => next(err))
.catch((err) => next(err));
}, (err) => next(err))
.catch((err) => next(err));
}
}
}
}, (err) => next(err))
.catch((err) => next(err));
})
При выполнении части if она выполняется без ошибок, но при выполнении else отображается длинный список ошибок.
POST /favorites/ 200 7.864 ms - 29
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:518:11)
at ServerResponse.header (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibresponse.js:767:10)
at ServerResponse.send (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibresponse.js:170:12)
at done (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibresponse.js:1004:10)
at Object.exports.renderFile (E:CourseraMERNNodeJSconFusionServernode_modulesjadelibindex.js:374:12)
at View.exports.__express [as engine] (E:CourseraMERNNodeJSconFusionServernode_modulesjadelibindex.js:417:11)
at View.render (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibview.js:135:8)
at tryRender (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibapplication.js:640:10)
at Function.render (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibapplication.js:592:3)
at ServerResponse.render (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibresponse.js:1008:7)
at E:CourseraMERNNodeJSconFusionServerapp.js:84:7
at Layer.handle_error (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibrouterlayer.js:71:5)
at trim_prefix (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibrouterindex.js:315:13)
at E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibrouterindex.js:284:7
at Function.process_params (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibrouterindex.js:335:12)
at next (E:CourseraMERNNodeJSconFusionServernode_modulesexpresslibrouterindex.js:275:10)
Как исправить эту проблему? Спасибо!
Комментарии:
1. Мои ожидания от кода заключаются в том, что если любимый документ не существует для пользователя, т. Е. Пользователь добавляет свое первое блюдо в избранное, затем создайте
Favorites
документ. И если пользователь добавляет dish во второй раз или далее, то он следует кодуelse
блока. Пользователь может добавить массив dish_id, и код обязан проверить, присутствует ли определенный идентификатор в избранном, а затем проигнорировать его с сообщением «он уже в dishes», иначе добавьте новое блюдо в избранное.
Ответ №1:
Убедитесь в return
каждом res.json()
заявлении, иначе код продолжит выполнять строки под ним, и у вас есть код, который устанавливает заголовки в нескольких местах, что вызывает ошибку:
.post(cors.corsWithOptions, authenticate.verifyUser, (req, res, next) => {
Favorites.findOne({user: req.user._id})
.then((favs)=> {
if(!favs) {
Favorites.create({user: req.user._id, dishes: req.body})
.then((favs)=> {
console.log('Favs created: ', favs);
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
return res.json(favs);
}, (err) => next(err))
.catch((err) => next(err));
}
else {
var noofids = req.body.length;
for (var i=0; i<noofids ; i ) {
if(favs.dishes.indexOf(req.body[i]._id) > -1) {
return res.json('It is already in the dishes');
}
else {
favs.dishes.push(req.body[i]._id);
favs.save()
.then((doc) => {
Favorites.findById(doc._id)
.populate('User').populate('Dishes')
.then((fav) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
return res.json(fav);
}, (err) => next(err))
.catch((err) => next(err));
}, (err) => next(err))
.catch((err) => next(err));
}
}
}
}, (err) => next(err))
.catch((err) => next(err));
})
Комментарии:
1. Проблема все еще не решена, сэр. Когда программа возвращается
return res.json('It is already in the dishes')
, она завершает работу и ожидает другого запроса. Я объяснил, как работает моя программа, добавив комментарий к моему вопросу. Короче говоря, я хочу, чтобы я добавил массив идентификаторов в тело, и код начнет проверять, присутствует ли конкретный идентификатор в избранном или нет. Если они присутствуют, то сделайте этоreturn res.json('It is already in the dishes')
, а если нет, то добавьте в избранное. И если я удалю return изreturn res.json('It is already in the dishes')
, то он начнет выдавать ту же ошибку HTTP_HEADERS2. Я думаю, что это может быть внутри цикла for, поэтому вы устанавливаете заголовки несколько раз
3. Итак, какие изменения я должен внести в это?
4. Выведите свои
return
инструкции из цикла иfav.dishes.push
, прежде чем возвращать какой-либо ответ клиенту, чтобы был отправлен только один ответ5. Извините, что ответил так поздно. Да! Это решило мою проблему. Я продолжал вводить массив в цикле for и сохранял его и отправлял заголовки один раз после цикла.