【问题标题】:Access the raw body of a request in koa.js在 koa.js 中访问请求的原始正文
【发布时间】:2015-11-20 08:02:18
【问题描述】:

我使用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;
  });

【问题讨论】:

    标签: javascript node.js koa


    【解决方案1】:

    只捕获一次流才有意义。

    您可以使用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"
    

    【讨论】:

      【解决方案2】:

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

      任何用于与其他请求主体使用者协调的主体解析器中间件(在 ctx.req 上侦听“数据”或“结束”事件的主体)必须确保它“同步”侦听事件(如“数据”或“结束”)在 ctx.req 上。对于在“Promise.resolve().then”中执行此操作的 co-body 和 koa-body(use co-body) 而言,情况并非如此,如果在侦听这些事件之前触发了“data”或“end”事件,则数据丢失(丢失“数据”事件)或错误(收听结束的流)将会发生。

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

      【讨论】:

        【解决方案3】:

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

        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];
        

        【讨论】:

        • > includeUnparsed {Boolean} 切换 co-body returnRawBody 选项;如果设置为 true,对于 form encodedand 和 JSON 请求,原始的、未解析的请求正文将使用 Symbol 附加到 ctx.request.body,默认为 false。此 koa-body 选项仅适用于“application/x-www-form-urlencoded”和“application/json”内容类型。对于“application/octet-stream”等其他类型,ctx.request.body中不会有未解析的body。
        猜你喜欢
        • 2015-10-19
        • 2020-07-19
        • 2010-11-06
        • 2018-11-27
        • 1970-01-01
        • 1970-01-01
        • 2019-02-20
        • 2017-06-25
        • 1970-01-01
        相关资源
        最近更新 更多