在koa.js中访问请求的原始正文

我已经使用io.js创建了一个API koa.js

作为我使用的身体解析器中间件koa-body,依次使用co-body

在我的一个API端点上,我正在接收POST请求,并且需要访问请求的原始主体,因为我需要对其进行编码以验证请求是否有效。

有什么方法可以访问请求的原始内容?我试图用raw-body中间件,但如果我用它我打电话之前koa-body,将co-body用于koa-body休息。如果我使用它后koa-body不起作用。

   app.use(function*(next){
    let rawRequestBody = yield rawBody(this.req);
    this.rawRequestBody = rawRequestBody;

    yield next;
  });

编辑:

我认为我找到了一种解决方法,但是我不知道这是否是最佳解决方案。我认为@greim答案可能是解决此问题的更好方法。

我在使用前添加了以下代码koa-body

app.use(function *(next) {

    let url = this.req.url;

    if(this.req.method == 'POST') {
      let that = this;
      this.req.rawBody = '';

      this.req.on('data', function(chunk) {
        that.req.rawBody += chunk;
      });
    }

    yield next;
  });
阿飞2020/04/07 11:55:45

只捕获一次流才有意义。

您可以使用raw-body实用程序将请求主体捕获为字符串或缓冲区(我假设这是“原始”主体的意思),然后保留对它的引用,如您自己的代码所示,例如:

let rawRequestBody = yield rawBody(this.req);
this.rawRequestBody = rawRequestBody;
console.log(typeof this.rawRequestBody); // "string"

一旦这样做,就不要再使用koa-bodyco-body,因为它们也是流捕获实用程序,它们假定您尚未捕获流。要使请求正文可作为JSON访问(例如),只需执行以下操作:

this.jsonRequestBody = JSON.parse(this.rawRequestBody);
console.log(typeof this.jsonRequestBody); // "object"
DavaidTony宝儿2020/04/07 11:55:45

为什么我们不能使用多个主体解析器(co-body,koa-body)是因为通过定义,它必须准备ctx.request.body供下一个中间件使用,这意味着当主体解析器中间件“ await next()”将控制权转移到下一个中​​间件ctx.req(或结束)。

任何与其他请求主体使用者(在ctx.req上侦听“数据”或“结束”事件的用户)协调的主体解析器中间件,都必须确保其在ctx上“同步”侦听事件(例如“数据”或“结束”)。要求 对于在“ Promise.resolve()。then”中执行的co-body和koa-body(使用co-body),这是不正确的,如果在监听一个事件之前触发了“ data”或“ end”事件,则数据丢失(丢失“数据”事件)或错误(听完流)。

@greim是正确的,但是在大多数情况下,我们使用高级中间件(例如joi-router),该中间件强制使用主体解析器中间件,并且我们无法控制,这仍然是一个问题。