在 koa.js 中访问请求的原始主体

Access the raw body of a request in koa.js

我使用 io.jskoa.js 创建了一个 API。

作为正文解析器中间件,我使用 koa-body,后者又使用 co-body.

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

有什么方法可以访问请求的原始主体吗?我尝试使用 raw-body 中间件,但如果我在调用 koa-body 之前使用它,则 koa-body 中使用的 co-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;
  });

抓流一次才有意义

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

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"

为什么我们不能使用 multiple body parser(co-body, koa-body) 是因为根据定义它必须准备 ctx.request.body 供下一个中间件使用,这意味着当一个 body 解析器中间件 "await next()" 将控制转移到下一个中​​间件 ctx.req 被消耗(或结束)。

任何用于与其他请求主体消费者(在 ctx.req 上监听 "data" 或 "end" 事件的消费者)协调的主体解析器中间件,必须确保它 "synchronize" 监听事件(如 "data" 或 "end")在 ctx.req 上。这对于在 "Promise.resolve().then" 中执行的 co-body 和 koa-body(使用 co-body)是不正确的,如果 "data" 或 "end" 事件在一个监听这些事件之前触发,数据丢失(丢失 "data" 事件)或错误(监听已结束的流)将发生。

@greim 是对的,但大多数时候,我们使用高级中间件(例如 joi-router),它强制使用 body parser 中间件而我们无法控制,这仍然是一个问题。

最好在文档中有一个快速入门代码示例,但似乎有 none。 这是我的一个工作示例:

const multipartBodyParser = require('koa-body');
const unparsed = require('koa-body/unparsed.js');

const app = new Koa();

app.use(multipartBodyParser({
  includeUnparsed: true,
  multipart: true,
}));

app.listen(3100);



// Now access the raw request body like this :
ctx.request.body[unparsed];

我在使用 koa-bodyparser 时遇到了类似的问题,问题是外部 webhook 没有发送 application/json 内容 header,所以它没有解析 [=15] =].我可以通过显式告诉解析器在这条路线上解析 json 来解决问题。

 .use(bodyParser({
      detectJSON: function (ctx) {
        return /webhook\/json-route/i.test(ctx.path);
      },
    }))

您可以通过 ctx.request.rawBody

访问原始请求正文

参考:enter link description here