?背景在基于Koa的框架(如EggJS)开发微信支付时,遇到一个问题:微信支付平台会发送一个回调请求,通知支付订单的处理结果。请求中传递的参数是xml格式的,但是koa中间件koa-bodyparser并没有对xml格式的请求参数进行处理,这就需要我们自己在程序中处理通用的处理逻辑了。网上一般的处理逻辑类似如下代码:constbb=require('bluebird');constxml=awaitbb.fromCallback(cb=>{letdata='';this.ctx.req.setEncoding('utf8');this.ctx.req.on('data',function(chunk){数据+=chunk;});this.ctx.req.on('end',function(){cb(null,data);});});分析与提问上面的代码是通过响应request对象的事件来接收xml数据的。对于微信支付场景来说简单有效,但是作为通用的xml处理机制还是有所欠缺。请求对象有以下事件:中止、关闭、数据、结束、错误。另外,请求参数可以使用压缩算法。如何更完整地处理这些场景?借用中间件koa-bodyparser因为基于Koa的框架(如EggJS)使用中间件koa-bodyparser来预处理请求参数。那么最完整的处理逻辑也一定是在中间件koa-bodyparser中。具体源码这里就不一一列举了,可以参考以下链接:https://github.com/cojs/co-body/blob/master/lib/json.jshttps://github.com/stream-utils/raw-body/blob/master/index.js通过分析中间件koa-bodyparser引用的源码,我们可以得到更加简洁的xml处理代码,适应的场景更加广泛。代码如下:constraw=require('raw-body');constinflate=require('通货膨胀');constxml=awaitraw(inflate(this.ctx.req));CabloyJS的进一步封装CabloyJS后端是基于EggJS定制的上层应用框架。CabloyJS在context对象中注入了一个通用方法getPayload,所以在实际开发中注入方法asyncgetPayload(options){returnawaitraw(inflate(this.req),options);}来真正调用constxml会更方便scenario=awaitthis.ctx.getPayload();
