我使用io.js
和koa.js
创建了一个API。
作为一个正文解析器中间件我正在使用koa-body
,后者又使用co-body
。
在我的一个API端点上,我收到了POST
个请求,我需要访问请求的原始主体,因为我需要对其进行编码以验证请求是否有效。
有没有办法访问请求的原始主体?我尝试使用raw-body
中间件,但如果我在调用koa-body
之前使用它,则co-body
中使用的koa-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;
});
答案 0 :(得分:6)
只捕获一次流才有意义。
您可以使用raw-body
实用程序将请求正文捕获为字符串或缓冲区(我假设这是您所说的" raw" body),然后将其作为参考保存为在您自己的代码中显示,例如:
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"
答案 1 :(得分:1)
为什么我们不能使用多个体解析器(co-body,koa-body)是因为通过定义它必须为下一个中间件准备ctx.request.body,这意味着当一个体解析器中间件“等待下一个( “”将控制转移到下一个中间件,ctx.req被消耗(或结束)。
用于与其他请求正文消费者协调的任何正文解析器中间件(一个在ctx.req上监听“数据”或“结束”事件),必须使其“同步”监听事件(如“数据”或“结束”)在ctx.req上。对于在“Promise.resolve()。then”中执行此操作的共同体和koa-body(使用共同体)不是这样,如果在监听这些事件之前触发“数据”或“结束”事件,则数据丢失(丢失“数据”事件)或错误(收听结束流)将会发生。
@greim是对的,但大多数时候,我们使用高级中间件(例如joi-router),它有强制使用正文解析器中间件而我们无法控制,这仍然是一个问题。
答案 2 :(得分:0)
在文档中有一个快速入门代码示例对此很好,但是似乎没有。 这是我的一个工作示例:
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];