Je ne sais pas vraiment pourquoi je reçois cette erreur. C'est une simple API construite sur express.js pour pouvoir ajouter et supprimer des publications. L'erreur se produit lorsque je déclenche le routeur de suppression. J'ai lu que l'erreur se produit généralement quand il y a deux rappels, cependant, je ne semble pas pouvoir trouver de double rappel.
_http_outgoing.js:344
throw new Error('Can\'t set headers after they are sent.');
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
at ServerResponse.header (/Users/bounty/Projects/_learning/react-express/node_modules/express/lib/response.js:718:10)
at ServerResponse.send (/Users/bounty/Projects/_learning/react-express/node_modules/express/lib/response.js:163:12)
at ServerResponse.json (/Users/bounty/Projects/_learning/react-express/node_modules/express/lib/response.js:249:15)
at /Users/bounty/Projects/_learning/react-express/server/routes/posts.js:86:9
at nextTickCallbackWith0Args (node.js:452:9)
at process._tickCallback (node.js:381:13)
Voici mon routeur posts.js:
module.exports = function(router) {
var Post = require('../models/post.js');
// middleware for the api requests
router.use(function(req, res, next) {
// do logging
console.log('something is happening.');
next(); // make sure we go to our next route and don't stop here
});
// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
// all routes here
// routes that end in /posts
router.route('/posts')
// create a Post (accessed at POST http://localhost:7777/api/posts)
.post(function(req, res) {
var post = new Post();
post.postTitle = req.body.postTitle; // set the post name (comes from request)
// save post and check for errors
post.save(function(err) {
if (err)
res.send();
res.json({ message: 'post created!' });
});
})
// get all Posts (accessed at GET http://localhost:7777/api/posts)
.get(function(req, res) {
Post.find(function(err, posts) {
if (err)
res.send();
res.json(posts);
});
});
// routes that end in /posts for specific id
router.route('/posts/:post_id')
// get the post with that id
.get(function(req, res) {
Post.findById(req.params.post_id, function(err, post) {
if (err)
res.send(err);
res.json(post);
});
})
// update the post with that id
.put(function(req, res) {
Post.findById(req.params.post_id, function(err, post) {
if (err)
res.send(err);
post.postTitle = req.body.postTitle;
// save the post
post.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'post updated!' });
});
});
})
// deletes the post with that id
.delete(function(req, res) {
Post.remove({
_id: req.params.post_id
}, function(err, post) {
if (err) {
res.send(err);
}
res.json({ message: 'post deleted!' });
});
});
}
Vous devez ajouter le «retour» pour ne pas répondre deux fois.
// save post and check for errors
post.save(function(err) {
if (err) {
return res.send();
}
res.json({ message: 'post created!' });
});
Ce message d'erreur particulier est presque toujours dû à une erreur de synchronisation dans le traitement d'une réponse asynchrone qui vous oblige à essayer d'envoyer des données sur une réponse après que la réponse a déjà été envoyée.
Cela se produit généralement lorsque des personnes traitent une réponse asynchrone dans un itinéraire express comme une réponse synchrone et finissent par envoyer des données deux fois.
Je pense que vous obtiendrez un emplacement dans l'un de vos chemins d'erreur:
Quand tu fais ça:
// save post and check for errors
post.save(function(err) {
if (err)
res.send();
res.json({ message: 'post created!' });
});
Si post.save()
génère une erreur, vous ferez res.send()
et vous ferez res.json(...)
après. Votre code doit avoir une return
ou une else
afin qu'en cas d'erreur, vous n'exécutiez pas les deux chemins de code.
Cela peut donc se produire dans Express lorsque vous tentez d'envoyer res.end
deux fois, ce que font res.send
et res.json
. Dans votre bloc if(err)
, vous souhaiterez utiliser return res.send()
car res.send
sera exécuté de manière asynchrone et res.json
sera également appelé. Je me demande si vous obtenez une erreur dans votre itinéraire delete
? J'espère que cela t'aides.
Meilleur!
Vous utilisez res.send()
ou res.json()
deux fois dans la même demande
ceci envoie les en-têtes en premier, suivi du corps de la réponse, puis de nouveau en-tête .req.next
n'est généralement pas une fonction, next
est plutôt passé comme troisième argument du middleware. Utilisez-le si vous voulez passer au middleware suivant. (en supposant que vous utilisez le framework Express)
If you are using res.send() inside any loop, then you need to break it after the use of res.send(). So that it won't allow resetting of the res headers again and again.
for e.g :
for(){
if(){
res.send();
break;
}
else(){
res.send();
break;
}
}
In my case this is the problem and I solved it like this.
Hope it may help someone in future.
Thanks