错误:发送后无法设置标头(NodeJS)

时间:2018-03-23 12:53:03

标签: node.js mongodb express checkout

我正在Nodejs-Express-MongoDB中构建像webapp这样的电子商务,我想用以下代码实现的目的是在用户结账后更新可用的商品库存。

当我尝试更新for loop内的库存时(如果没有按预期执行),会出现错误。

router.get('/checkout',function(req,res){
 if (!req.session.cart) {
  return res.redirect('cart');
 }
 else{
  var cart = new Cart(req.session.cart);
  var order = new Order({
    user: req.user,
    cart: cart
  });

  order.save(function(err,result)
  {
    var products = cart.generateArray();
    console.log(products);

    for(var i=0; i<products.length; i++)
    {
      Item.findById(products[i].item._id ,function(err,findedItem){
        if(err) {
          res.json(err);
        }
        if(findedItem) {
          var stock=findedItem.stock;
          console.log("* AVAILABLE STOCK: "+stock);

          if(stock < products[i].qty){
            req.flash('info', 'Ups, we can't serve this order');
            return res.redirect('/items/cart');
          }
          else{
            console.log("wrrkd!");
            Item.updateItem(products[i].item._id,products[i].qty);
          } 
        }         
      })
    }
    req.session.cart=null;
    res.redirect('/items/home');
  })
 } 
});

首先使用cart.generateArray(),我将产品存储在一个包含所有购买商品的数组中。然后我开始在我的物品模型(商店所有物品都在哪里)中搜索物品,以便我可以稍后更新库存。

因此,如果至少一种产品的数量高于可用产品的数量,我希望它停止并返回购物车页面。如果没有,只需更新可用库存并转到主页。

Item.updateItem:

module.exports.updateItem = function(id,numItem,callback){
  Item.findById(id, function(err,findedItem){
    console.log("* UPDATING ITEM: "+findedItem.name);
    if(findedItem.stock > numItem){
      findedItem.stock -= numItem;
      findedItem.save(callback);
    } else if(findedItem.stock == numItem){
      Item.findByIdAndRemove(id,function(err) {
        if (err)
            res.send(err);
        else
          console.log("* DELETING ITEM: "+findedItem.name);
      });
    }
  })
}

我得到以下错误,我尝试调试,但我不知道如何解决它:

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (C:\...\node_modules\express\lib\response.js:767:10)
    at ServerResponse.send (C:\...\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\...\node_modules\express\lib\response.js:267:15)
    at C:\...\routes\items.js:58:17
    at C:\...\node_modules\mongoose\lib\model.js:3930:16
    at _init (C:\...\node_modules\mongoose\lib\query.js:2000:14)
    at completeOne (C:\...\node_modules\mongoose\lib\query.js:1995:5)
    at Immediate.<anonymous> (C:\...\node_modules\mongoose\lib\query.js:1520:11)
    at Immediate._onImmediate (C:\...\node_modules\mquery\lib\utils.js:119:16)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)

1 个答案:

答案 0 :(得分:0)

如果在设置标题之前写入输出,标题将自动设置。然后,当您重定向时,标头已设置,因此无法重定向。您只应在不想重定向时写入输出。因此,首先检查是否需要重定向。如果你无法检查它(这不是一件好事),你应该将输出保存在缓冲区中,然后在你确定不需要重定向时将其写入输出。