在 koa.js 中访问请求的原始主体
Access the raw body of a request in koa.js
我使用 io.js
和 koa.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-body
或 co-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
访问原始请求正文
我使用 io.js
和 koa.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-body
或 co-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
访问原始请求正文