在Koa系框架(如EggJS)中进行微信支付
开发时,遇到一个问题:微信支付平台会发送一个回调请求,通知支付订单的处理结果。该请求传入的参数是xml格式,而Koa中间件koa-bodyparser
对xml格式的请求参数没有作处理,这就须要咱们在程序中自行处理javascript
网上通用的处理逻辑,都是相似以下的代码:java
const bb = require('bluebird'); const xml = await bb.fromCallback(cb => { let data = ''; this.ctx.req.setEncoding('utf8'); this.ctx.req.on('data', function(chunk) { data += chunk; }); this.ctx.req.on('end', function() { cb(null, data); }); });
上面这段代码经过响应request对象的事件接收xml数据,对于微信支付
这个场景简单有效,可是做为一个通用的xml处理机制,仍是有所欠缺。request对象有以下事件:aborted
、close
、data
、end
、error
,此外,请求参数还有可能使用了压缩算法。如何对这些场景作更完整的处理呢?git
koa-bodyparser
因为Koa系框架(如EggJS)使用中间件koa-bodyparser
对请求参数作预处理工做。那么最完整的处理逻辑也必定在中间件koa-bodyparser
中。具体的源码这里不列出,能够参考以下连接:github
经过分析中间件koa-bodyparser
所引用的源码,咱们就能够获得一个更简洁的xml处理代码,并且适应场景也更广,代码以下:算法
const raw = require('raw-body'); const inflate = require('inflation'); const xml = await raw(inflate(this.ctx.req));
CabloyJS后端是基于EggJS定制的上层应用框架。CabloyJS经过向context对象注入一个通用的方法getPayload
,那么在实际的开发场景中就更加方便了json
async getPayload(options) { return await raw(inflate(this.req), options); }
const xml = await this.ctx.getPayload();