在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();