【问题标题】:Error: Can't set headers after they are sent Braintree错误:在发送 Braintree 后无法设置标题
【发布时间】:2016-12-31 14:24:37
【问题描述】:

我目前正在为我正在创建的这个网站开发一个管理面板,因此我可以通过 Braintree 接受付款,但我需要实现检索客户交易的功能,但是一旦发送了标题,它只会发送一个他们,而不是整个事情。是否可以将 json 组合到一个数组中,以便将其发送到一个标头中?

代码:

router.get('/:cid/test', function(req, res) {
  var stream = gateway.transaction.search(function (search) {
  search.customerId().is(req.params.cid);
  }, function (err, response) {
    response.each(function (err, transaction) {
      return res.render('admin/test', {transaction: transaction});
    });
  });
});

这完全遵循 Braintree 文档,我确切地知道错误发生的原因。任何帮助都非常感谢,我很擅长解释,所以如果您需要了解更多信息,请给我打电话!

更新:所以,我想我会探索另一种方法,我注意到“响应”会返回一个 id 数组。所以我将只使用 EJS 循环所有这些,然后为每个事务创建一个单独的页面。

【问题讨论】:

  • 如果它可以转换为数组,我肯定可以用 EJS 循环它。
  • Braintree 的人在这里闲逛,我最后一次看到,但我上次使用他们通过电子邮件提供的技术支持非常好。你应该试试。正如您所发现的,他们的文档很糟糕。
  • 他们确实有很好的电子邮件支持,但不幸的是他们在新年期间关闭,是的,这太可怕了哈哈。
  • 您使用的是 Express 吗?我认为这不是 Braintree 的问题,而是 Express(或您可以使用的任何其他工具)的问题,所以我认为这些信息至关重要。

标签: node.js braintree


【解决方案1】:

免责声明:我为 Braintree 工作 :)

正如 Robert 所指出的,您只能在每个请求中调用一次 res.render(或 end 请求的任何响应方法)(因此出现 express 错误)。

不幸的是,您不能将response 视为一个数组,因此您需要使用 与search responses 交互的两种记录方式之一。我个人更喜欢流方法,因为它更清晰:

app.get('/stream', function (req, res) {
  var transactions = []
  var transactionStream = gateway.transaction.search(function (search) {
    search.customerId().is(req.params.cid);
  })

  transactionStream.on('data', function (transaction) {
    transactions.push(transaction)
  })

  transactionStream.on('error', function () { /* handle errors */ })

  transactionStream.on('end', function () {
    res.json({transactions: transactions});
  })
})

或者,您可以使用responseids 属性来比较您从each 构建的事务数组,以了解何时结束请求:

app.get('/calback', function (req, res) {
  var transactionStream = gateway.transaction.search(function (search) {
    search.customerId().is(req.params.cid);
  }, function (err, response) {
    var transactions = []
    response.each(function (err, transaction) {
      transactions.push(transaction)
      if (transactions.length === response.ids.length) {
        res.json({transactions: transactions});
      }
    })
  })
})

【讨论】:

    【解决方案2】:

    每个路由只能呈现一个响应。所以你只能调用一次,不能循环调用:

    res.render('admin/test', {transaction: transaction}); });
    

    您可以使用 each 方法遍历响应并构建结果:

    var transactions =[];
    response.each(function (err, transaction)   { transactions.push(transaction) });
    return res.render('admin/test', {transaction: transactions});
    

    如果每个方法都是同步的,那将起作用。如果不是(尼克会知道),请使用以下解决方案。

    【讨论】:

    • 很遗憾response 在这里不是一个数组,它是一个带有each 方法的对象(这很混乱吗,是的:))
    猜你喜欢
    • 2015-11-13
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 2019-07-17
    • 1970-01-01
    相关资源
    最近更新 更多