2016-01-25 16 views
19

Ben bu hatayı alıyorum neden gerçekten emin değilim gönderildikten sonra. Yayın ekleyebilmeniz ve kaldırabilmeniz için express.js üzerinde oluşturulmuş basit bir API. Silme yönlendiricisini tetiklediğimde hata oluşur. İki geri aramaları olduğunda hata genellikle ancak, herhangi bir çift geri aramalar bulmak mümkün görünmüyor, bunlar olabilir okudum. İşte Express.js Yönlendirme hatası: Başlıkları ayarlanamaz onlar

_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) 

benim posts.js yönlendiricidir: Belirli hata mesajı hemen hemen her zaman çünkü gönderme girişimine neden olan bir zaman uyumsuz yanıtının işlemedeki bir zamanlama hatası neden olur Yani

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!' }); 
      }); 
     }); 
} 
+0

Ne gönderiyor.save() 'veya' post.find() 'aslında yapar? Bu senin veritabanın mı? – jfriend00

+0

@ jfriend00 Evet, kaydet() veritabanına bir yazı yerleştirir. Bul() veritabanındaki mesajları alır. Veritabanı MongoDB'dir. – bounty

cevap

50

İki kez yanıt vermemek için 'dönüşü' eklemeniz gerekir.

// save post and check for errors 
post.save(function(err) { 
    if (err) { 
     return res.send(); 
    } 
    res.json({ message: 'post created!' }); 
}); 
+0

teşekkürler! Bu işe yaramış gibi görünüyor. – bounty

+0

Teşekkürler! Bu cevap sorunun bir kısmını çözdü. Bununla saatlerce uğraşıyorum. – AllJs

+0

Ara katman yazarken, sonraki aramaya birden fazla çağrıya göz atın() –

12

Yanıt verildikten sonra bir yanıt hakkında veriler. insanlar bir senkron tepki olarak bir ekspres yolu içinde bir zaman uyumsuz tepkisini tedavi etmek ve onlar iki kez veri göndermeyi sonuna kadar zaman

Genellikle olur.

Bunu yaptığınızda: post.save() bir hata üretir

 // save post and check for errors 
     post.save(function(err) { 
      if (err) 
       res.send(); 

      res.json({ message: 'post created!' }); 
     }); 

varsa, res.send() yapacak ve sana bu alacağı bkz


Bir yerde Hata yollardan herhangi birinde olduğu Daha sonra res.json(...) yapacaktır. Kodunuz bir hata olduğu zaman bir return veya else böylece hem kod yollarını idam etmiyoruz olması gerekir. res.send ve res.json ikisini de iki kez res.end göndermeye çalışırken

4

Yani, bu Express'te gerçekleşebilir. senin if(err) bloğunda zaman uyumsuz return res.send()res.send olarak çalışır isteyeceksiniz ve res.json yanı adlandırılan oluyor. delete rotanızda bir hata alıp almadığınızı merak ediyorum. Bu yardımcı olur umarım.

En İyi!

0
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 
3

Ardından başlıkları tekrar yanıtın vücut tarafından takip edilen ve bu birinci başlıkları göndermek aynı istek

iki kez res.send() veya res.json() kullanıyor. req.nextnext yerine katman üçüncü bir bağımsız değişken olarak geçirilir, genellikle bir fonksiyonu değildir. Bir sonraki katman yazılımına geçmek istiyorsanız bunu kullanın. Sadece ben de söz edecek bütünlük uğruna

1

(Ekspres çerçevesini kullanan varsayarak): Bazen sorun app.use arayarak Kullanıyor olabileceğiniz bir katman olabilir.

önceki yanıtlarında belirtildiği gibi bariz hatalar için kontrol ettikten sonra:

Daha sonra, teker teker yeniden gündeme tüm app.use ifadeyi kaldırmak gerekir sorunlu modülü bulmak için.