2016-01-25 19 views
19

なぜこのエラーが発生するのかわかりません。これは、投稿を追加したり削除したりするためにexpress.js上に構築されたシンプルなAPIです。このエラーは、削除ルータを起動するときに発生します。私は2つのコールバックがあるときにエラーが発生するのが普通ですが、ダブルコールバックが見つからないようです。ここで Express.jsルーティングエラー:送信後にヘッダーを設定できません

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

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

「投稿」とは何ですか?save() 'や' post.find() 'は実際にどうしますか?これはあなたのデータベースですか? – jfriend00

+0

@ jfriend00はい、save()は投稿をデータベースに入れます。 Find()は、データベースからの投稿を取得します。データベースはMongoDBです。 – bounty

答えて

50

「返信」を追加すると、2回返信しないようにする必要があります。

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

ありがとう!これはうまくいったようです。 – bounty

+0

ありがとう!この回答は問題の一部を解決しました。私はこれと何時間も闘ってきました。 – AllJs

+0

ミドルウェアを書くときは、next()への複数の呼び出しを見てください –

12

応答が既に送信された後の応答に関するデータ。

通常、高速応答経路内の非同期応答を同期応答​​として扱い、データを2回送信することがあります。

あなたがこれを行うと:私はあなたがこれはあなたのエラーパスのいずれかであるになるだろう参照


場所の一つ

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

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

post.save()がエラーを生成する場合は、res.send()を行いますと、その後、res.json(...)を実行します。コードにはreturnまたはelseが必要です。エラーが発生した場合は、両方のコードパスを実行しないでください。

4

これは、res.sendres.jsonの両方が実行するres.endを2回送信しようとすると、Expressで発生する可能性があります。 if(err)ブロックでは、return res.send()にはres.sendが非同期に実行され、res.jsonも呼び出されます。 deleteルートでエラーが発生しているのですか?お役に立てれば。

ベスト!

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

あなたはこのレスポンスのボディに続いて、再度ヘッダ、最初のヘッダーを送信する同じ要求

に二回res.send()またはres.json()を使用しています。 req.nextは通常は関数ではなく、nextがミドルウェアの3番目の引数として渡されます。次のミドルウェアにドロップしたい場合は、これを使用します。ただ、私もそれを言及します完全を期すために

1

を(あなたがエクスプレスのフレームワークを使用していると仮定します): いつか問題が app.useを呼び出すことによって、あなたが使用している可能性がありミドルウェアであってもよいです。

前回の回答で述べたように明白なエラーをチェックした後:

あなたは問題のモジュールを見つけるために、それらを一つ一つを再導入、すべてのapp.use文を削除する必要があります。

関連する問題