Node版本比较老,koa1.x配合koa-body-parser,默认koa-body-parser会把请求数据转成json对象,

  然而有的时候需要获取原始的内容,不要转换,看波koa-body-parser源码,找到办法。

  办法一:设置请求头Content-type值为:text/plain

  

  这样ctx.request.body就是一个字符串了.

  缺点:要毅端加东西,想到前端的懒惰,较困难,放弃。

  

  继续摸索源码,发现一个办法,代码:

const koa = require('koa');
const router = require('koa-router');
const bodyParser = require('koa-body-parser'); const app = new koa();
const a = new router(); function injectRawBody(rawBodyName) {
return function* (next) {
const ctx = this;
let _rawBody = yield function (done) {
let received = '';
function onData(chunk) {
received += chunk;
}
function onEnd() {
ctx.req.removeListener('data', onData);
ctx.req.removeListener('end', onEnd);
done(null, received);
}
}
ctx.request[rawBodyName] = _rawBody;
yield next;
}
} app.use(injectRawBody('rawBody')); app.use(bodyParser(); const server = require('http').createServer(app.callback());
app.use(a.routes());
a.post('/a', function* () {
const ctx = this;
const body = ctx.request.body;
console.log("ctx.request.body:", body);
console.log("type of ctx.request.body:", typeof body); console.log("raw body:", Buffer.concat(ctx.request.rawBody).toString());
console.log("type of raw body:", typeof ctx.request.rawBody); yield tt.addOrCreate.apply(ctx);
ctx.body = 'success'; });
server.listen(3000);

  运行,看输出,成功把原始内容挂在ctx.request.rawBody上,但ctx.request.body却成了undefined,点解?

  经过细查,发现在koa-body-parser/index.js有一句判断:

  

  因为在上一个中间件,已经耗尽了req对象的数据,所以ended就是true,那也就不会进入之后的解析了。为了一点小私,导致依赖body的功能不能用,不行不行。

  既然我放在body-parser前面不行,那我能放到后面么?像这样:

app.use(bodyParser());
app.use(injectRawBody('rawBody'));

  答案是不行,因为在body-parser设置了req.once,而且即使没有设置once,body-parser只有耗尽了req对象(end事件)才会继续下一个中间件,下一个中间件不能再从已经读完的ReadableStream里重新读数据。

  

  

  再细细看波源码,co、koa-body-parser、co-body、raw-body真没发现什么好方法,这几个库之间的协作太无鏠了,基本上没法hack进去。

  想过伪装一个req对象,跟ctx.req有一样的接口,让koa-body-parser里操作的是这个伪装的对象,完了之后再恢复,但没试出来,暂时放弃。

  束手无措之际,突然想起晚上在stackoverflow上看到有人问过同样的问题,回忆了一下其中一个回答,当时觉得没怎么样,现在想想真是可以用,代码:

const koa = require('koa');
const router = require('koa-router');
const bodyParser = require('koa-body-parser');

const app = new koa();
const a = new router(); function injectRawBody(rawBodyName) {
return function* (next) {
const ctx = this;
let received = [];
function data(chunk) {
received.push(chunk);
}
ctx.req.on('data', data);
ctx.request[rawBodyName] = received;
yield next;
}
} app.use(injectRawBody('rawBody')); app.use(bodyParser(); const server = require('http').createServer(app.callback());
app.use(a.routes());
a.post('/a', function* () {
const ctx = this;
//console.log(ctx.request);
const body = ctx.request.body;
console.log("ctx.request.body:", body);
console.log("type of ctx.request.body:", typeof body); console.log("raw body:", Buffer.concat(ctx.request.rawBody).toString());
console.log("type of raw body:", typeof ctx.request.rawBody); yield tt.addOrCreate.apply(ctx);
ctx.body = 'success'; }); server.listen(3000);

  在injectRawBody中间件,绑定了data事件,接收数据。而body-parser只有在end事件发生时才会resolve,所有在injectRawBody里,获取到的是完事的数据,只是存的是buffer,使用的时候需要转换为字符串。

  优点:没有body-parser那样的限制数据大小,buffer想放多少放多少,不受node堆限制;

     简单,容易实现。

  缺点:需要转换成字符串,不会转的还可能出现乱码。

  

  

最新文章

  1. ios http请求
  2. 黑马程序员_Java基础:多线程总结
  3. indeterminateDrawable
  4. List对象排序的通用方法
  5. ListableBeanFactory
  6. USACO Section 2.2: Party Lamps
  7. 2.RxJava详解网址http
  8. session劫持以及预防
  9. PHP Yii框架开发——组织架构网站重构
  10. Spring接口编程_设值注入和构造注入
  11. HDnoip2017题解
  12. Hadoop:Hadoop简介及环境配置
  13. mac git从代码仓库克隆代码,修改并上传
  14. django 2.接口之工作原理
  15. 微信商户/H5支付申请 被拒原因:网站存在不实内容或不安全信息
  16. Apollo
  17. centos 6.5 查看时区和设置时区
  18. 【Gym - 100796C 】Minimax Tree
  19. 129. Sum Root to Leaf Numbers pathsum路径求和
  20. [SoapUI] 检查测试步骤的类型或者或者某种特定类型的步骤列表

热门文章

  1. LintCode——交叉字符串
  2. 关于几个vcenter的合并心得!
  3. 阿里云ubuntu16.04安装ruby
  4. Bootstrap 样式设计 栅格系统
  5. Macaca初体验-PC端(Python)
  6. Substrings (C++ find函数应用)
  7. M2 Daily SCRUM要求
  8. LeetCode 167. 两数之和 II - 输入有序数组
  9. Book Review 《构建之法》
  10. 如何向妻子解释OOD