【问题标题】:Can't remove headers after they are sent发送后无法删除标头
【发布时间】:2016-11-21 20:38:44
【问题描述】:

我从我的服务器收到不一致的结果。有时会发送正确的响应,有时我会收到错误

发送后无法删除标头

使用 Node.js、Koa.js 和 Mongoose

router
.get('/events/', function* getEvent() {
  let eventList = [];
  yield Event.find({}, (error, events) => {
    if (error) {
      this.response.body = 'Unable to get events.';
      this.status = 404;
      return;
    }

    eventList = events;
    eventList.sort((first, second) => {
      // sort implementation
    });

    this.response.body = eventList;
    this.status = 200;
  });
});

【问题讨论】:

  • 这通常是由不一致的 res.end() 调用引起的。如果不是这样,您能否提供更多上下文或代码?
  • 这有可能是因为您处理错误的方式(您也可以为此添加代码吗?)。此外,您的 yield 似乎是多余的,因为您还将回调传递给 Event.find()
  • @safaiyeh 对,但关注错误本身,它表示正在发送标头,然后尝试修改它们。至少对我来说,这表明调用要么被打了两次,要么你正在触发这个调用,而不是结束响应,并触发另一个与之冲突的 get/post
  • @safaiyeh 看起来不错。您没有使用可能导致错误的其他中间件?
  • 嗯,你正在使用路由器中间件。

标签: javascript node.js mongoose koa


【解决方案1】:

这个问题是由你的回调引起的,它引入了竞争条件,因为你的收益没有等待它完成。在 Koa v1.x 中,您通常只使用回调 API 来返回一个 Promise。

以下是使用 Koa v1.x 编写示例的方式:

router
  .get('/events', function * () {
    let events
    try {
      events = yield Event.find({})
    } catch (err) {
      this.status = 503
      this.body = 'Unable to get events'
      return
    }
    events = sort(events)
    this.body = events  // Implicit 200 response
  })

Event.find 只需要返回一些可以产生的东西,比如一个承诺。检查您使用的库是否具有返回承诺的版本。

虽然通常你会这样写:

router
  .get('/events', function * () {
    let events = yield Event.find({})
    events = sort(events)
    this.body = events
  })

如果Event.find 关闭,这是一个内部错误(500 响应)。 Koa 会将未捕获的错误转化为 500 个响应。

【讨论】:

    【解决方案2】:

    基本上,将this.status设置为200后,它会抛出错误,因为this.response.body可能是undefined.继续console.log()this.response.body,看看它是否被定义。如果是undefined,我猜req.body 没有正确填充或者是异步节点问题。基本上, eventList.sort() 是在设置 this.response.body = eventList 时异步执行的。因此,当您设置 eventList 时,它还没有排序。要解决此问题,请将其放入 eventList.sort() 回调中。

    编辑:看到您的评论后,我很确定这是异步问题。让我知道将最后两行放在排序调用中是否适合您。

    【讨论】:

    • 添加了停止排序调用的行,问题仍然存在。
    • 请让我知道 this.response.body 中的 console.log 中有什么
    • 我突然想到:你可能想要this.request.body,而不是this.response.body
    • 我添加了 console.log(this.response.body);分配后。 IT 在记录之前就崩溃了。成功时,定义响应。
    • this.request.body 未定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 2013-04-06
    相关资源
    最近更新 更多