最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Access the raw body of a request in koa.js - Stack Overflow

programmeradmin4浏览0评论

I have created an API using io.js and koa.js.

As a body parser middleware I am using koa-body, which in turn uses co-body.

On one of my API endpoints I am receiving POST requests, and I need access to the raw body of the request, because I need to encode it to verify if the request is valid.

Is there any way to access the raw body of the request? I tried to use the raw-body middleware, but if I use it before I call koa-body, the co-body used in koa-body breaks. If I use it after koa-body it does not work.

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

    yield next;
  });

EDIT:

I think that I found a workaround, but I don't know if this is the best solution. I think that @greim answer may be a better solution to this problem.

I added the following code before I use 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;
  });

I have created an API using io.js and koa.js.

As a body parser middleware I am using koa-body, which in turn uses co-body.

On one of my API endpoints I am receiving POST requests, and I need access to the raw body of the request, because I need to encode it to verify if the request is valid.

Is there any way to access the raw body of the request? I tried to use the raw-body middleware, but if I use it before I call koa-body, the co-body used in koa-body breaks. If I use it after koa-body it does not work.

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

    yield next;
  });

EDIT:

I think that I found a workaround, but I don't know if this is the best solution. I think that @greim answer may be a better solution to this problem.

I added the following code before I use 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;
  });
Share Improve this question edited Aug 31, 2015 at 6:55 Ivan Stoyanov asked Aug 26, 2015 at 10:19 Ivan StoyanovIvan Stoyanov 5,48212 gold badges58 silver badges72 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 9

It only makes sense to capture the stream once.

You can capture the request body as a string or buffer (I assume this is what you mean by "raw" body) using the raw-body utility, and then keep a reference to it as shown in your own code, such that:

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

Once you do that, don't also use koa-body or co-body, since those are also stream-capturing utilities which assume you haven't yet captured the stream. To make the request body accessible as JSON (for example) simply do this:

this.jsonRequestBody = JSON.parse(this.rawRequestBody);
console.log(typeof this.jsonRequestBody); // "object"

Why we can't use multiple body parser(co-body, koa-body) is because by defination it must prepare ctx.request.body for next middleware to use, this means when a body parser middleware "await next()" to transfer control to next middleware the ctx.req is consumed(or end).

Any body parser middleware for coordination with other request body consumer(one that listen "data" or "end" event on ctx.req), must makesure it "synchronize" listen events(like "data" or "end") on ctx.req. This is not true for co-body and koa-body(use co-body) which do it in "Promise.resolve().then", if "data" or "end" events triggered before one listen these event, data missing(lose "data" event) or error(listen on ended stream) will happen.

@greim is right, but most of the time, we use a high level middleware(such as joi-router) which has force to use a body parser middleware and we have no control, this is still a problem.

It would be nice to have a quickstart code example in the docs for this, but it seems like there's none. Here's a working example that I have:

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

I had a similar problem using koa-bodyparser and the problem was that the external webhook didn't sent the application/json content header, so it did not parsed the body. I could solve the problem by explicitly telling the parser to parse json on this route.

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

You can access raw request body by ctx.request.rawBody

ref: enter link description here

发布评论

评论列表(0)

  1. 暂无评论