# 一、描述
koa 处理 post 请求的时候,需要对 body 传递过来的数据进行处理。
实际上如果要手动实现一个能够处理 application/x-www-from-urlencoded 的中间件,还是借助的原生 node.js 的方法进行处理。
koa 封装了原生了 node.js 的 request 对象到 ctx.req 中。
而借助原生 node.js 的 request 对象,监听 data 事件及 end 事件,进行处理。
# 二、实现中间件
# 1、实现 listen 监听 body 数据传输
当 body 数据传输结束后,将拼接的字符串进行解析,解析之后,将 Promise resolve 即可。
| function listen(ctx){ | |
| let str = ''; | |
| return new Promise((resolve,reject) => { | |
| ctx.req.addListener('data',(data)=>{ | |
| str += data; | |
| }); | |
| ctx.req.addListener('end',()=>{ | |
| const res = jsonBodyparser(str); | |
| resolve(res); | |
| }); | |
| }); | |
| } | 
# 2、将字符串解析成对象
处理拼接的字符串很简单,我用了最简单的方式,就是拆分遍历字符串。
| function jsonBodyparser(str){ | |
| let parseBody = {}; | |
| let strArr = str.split('&'); | |
| for(let [index,item] of strArr.entries()){ | |
| const itemArr = item.split("="); | |
| parseBody[itemArr[0]] = itemArr[1]; | |
|   } | |
| return parseBody; | |
| } | 
# 3、export 中间件
参照了 koa-bodyparser 中间件实现方式,将结果封装进了 ctx.request.body 中
| module.exports = () => { | |
| return async (ctx, next) => { | |
| bodyParser = await listen(ctx); | |
| ctx.request.body = bodyParser; | |
| await next(); | |
|   } | |
| } | 
# 三、 使用中间件
| const Router = require('koa-router'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const postBodyParser= require('../middlewares/postBodyParser'); | |
| const router = new Router(); | |
| router.use(postBodyParser()); | |
| router.get('/',async (ctx)=>{ | |
| const htm = fs.readFileSync(path.resolve('./views/login.html')).toString(); | |
| ctx.body = htm; | |
| }).post('/',async (ctx)=>{ | |
| ctx.body = ctx.request.body; | |
| }); | |
| module.exports = router; | 
# 四、使用 koa-bodyparser
如果使用 koa-bodyparser ,则非常方便而且考虑的方面也更多。
# 1、安装
yarn add koa-bodyparser
# 2、引入
| const Koa = require('koa'); | |
| const Router = require('koa-router'); | |
| const bodyParser = require('koa-bodyparser'); | |
| const router = require('./routes/index'); | 
# 3、使用
接上面 【 引入 】
| const app = new Koa(); | |
| app.use(bodyParser()); | |
| app.use(router.routes()).use(router.allowedMethods()); | |
| app.listen(5000,()=>{ | |
| console.log('start : 5000'); | |
| }); | 
