Access to the raw request body in koa.js

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

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

At one of my API endpoints, I get POST requests and I need access to the raw body of the request because I need to encode it to check if the request is valid.

Is there a way to access the unprocessed request body? I tried using the raw-body middleware, but if I use it before I call koa-body , then the co-body used in koa-body is broken. 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 I found a workaround, but I don't know if this is the best solution. I think @greim's answer might be the best solution to this problem.

I added the following code before using 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; }); 
+6
source share
3 answers

The only point is to capture the thread once.

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

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

Once you do this, do not use koa-body or co-body either, as these are also stream capture utilities that assume you haven't captured the stream yet. To make the request body accessible as JSON (for example), simply do the following:

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

Why can't we use several body parsers (co-body, koa-body), because by defining it must prepare ctx.request.body for using the following middleware, that means after the middle of the body parser " waits for the next "()" to transfer control to the next middleware, ctx.req is consumed (or ends).

Any connecting means for the body analyzer to coordinate with another consumer of the request body (one that listens for “data” or “completes” the event on ctx.req) should make it “synchronize” listening events (for example, “data” or “end” ) on ctx.req. This does not apply to the joint body and coa-body (use the co-body) that do this in "Promise.resolve ()", and then "if the events" data "or" end "are fired before you listen this event, data is missing (lose "data") or error (listening on a completed stream).

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

+1
source

It would be nice to have an example quick code in the documentation for this, but it doesn't seem to be there. Here is 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]; 
0
source

All Articles