node express / request:使用正文解析来管理POST请求

时间:2017-06-15 12:18:02

标签: javascript node.js express node-request

我试图通过远程服务器管理处理请求,其行如下:

var destination = request(url);
req.pipe(destination).pipe(res);

这适用于GET个请求。但对于POST请求,我正在挣扎。我认为,需要注意的一点是,对于POST请求,我在POST路由处理程序之前使用了一个正文解析器,以便从POST请求中提取正文...它只是一个基本的文本正文解析器,因为正文包含纯文本:

var postRouteHandler = someFunction;
var bodyParser = require('body-parser');
var textParser = bodyParser.text({
    limit: '50kb'
});
app.use('/postRoute', [textParser, postRouteHandler]);

this issuethis issue我觉得在管道之前对POST请求进行任何处理都会导致问题。实际上,当我删除解析器时,管道似乎工作正常。

问题是我需要首先检查主体,进行一些初始处理,然后确定是否将请求通过管道传输到远程服务器上。所以我需要在滚动之前解析主体。

有没有解决这个问题的方法?

3 个答案:

答案 0 :(得分:10)

问题在于使用流(例如req),一旦您阅读了它,就无法重置它。

由于body-parser已经读取了流,因此管道将无法正常工作,因为这会尝试再次读取流(此时已经用完了)。

解决方法是使用body-parser读取的文本,并创建一个最小req“克隆”,以便request能够传递请求:

var intoStream = require('into-stream');
var bodyParser = require('body-parser');
var textParser = bodyParser.text({ limit: '50kb' });

var postRouteHandler = function(req, res) {
  let text = req.body;
  if (! shouldPipe(text)) {
    return res.sendStatus(400); // or whatever
  }

  // Here's where the magic happens: create a new stream from `text`,
  // and copy the properties from `req` that `request` needs to pass
  // along the request to the destination.
  let stream     = intoStream(text);
  stream.method  = req.method;
  stream.headers = req.headers;

  // Pipe the newly created stream to request.
  stream.pipe(request(url)).pipe(res);
};
app.use('/postRoute', [textParser, postRouteHandler]);

答案 1 :(得分:1)

如果解析器导致问题,您应该创建自己的中间件。老实说,你可能想要以与身体解析器不同的方式解析身体。

鉴于对项目其余部分正在做什么的了解有限,您可以创建中间件来挂钩正文解析器中间件,然后发送请求的克隆。然而,这并不是非常有效,但可以起作用,可能有助于指明您正确的方向。

var postRouteHandler = someFunction;
var bodyParser = require('body-parser');
var textParseMiddleware = function (req, res, next) {

  var requestclone = _.clone(req);
  var textParser = bodyParser.text({
    limit: '50kb'
  });

  textParser(requestclone, res, function(){
    console.log('examine the body here', requestclone.body);
  });


}

app.use('/postRoute', [textParserMiddleWare, postRouteHandler]);

我还没有测试过上面的代码。

答案 2 :(得分:0)

需要通过POST发送大量大数据,我收到错误:socket挂断/代码:'ECONNRESET'。 能够通过增加身体解析器的限制来解决它。

var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json({limit:'50mb'}));