简体   繁体   English

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

[英]node express/request: piping a POST request with body parsing

I'm attempting to pipe a request for handling by a remote server, along the following lines: 我正在尝试通过以下方式管理远程服务器处理请求:

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

This works just fine for GET requests. 这适用于GET请求。 But for POST requests I'm struggling. 但对于POST请求,我正在努力。 An important point to note, I think, is that for POST requests I'm using a body parser before my POST route handler in order to extract the body from the POST request... it's just a basic text body parser because the body contains plain text: 我想,需要注意的一点是,对于POST请求,我在POST路由处理程序之前使用了一个正文解析器,以便从POST请求中提取正文...它只是一个基本的文本正文解析器,因为正文包含纯文本:

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

From this issue and this issue it seems to me that doing any processing on the POST request before you pipe it will cause a problem. 这个问题这个问题看来,在管道之前对POST请求进行任何处理都会导致问题。 Indeed, when I remove the parser, the piping seems to work OK. 实际上,当我删除解析器时,管道似乎工作正常。

The problem is that I need to examine the body first, to do some initial processing and then to determine whether or not to pipe the request on to the remote server at all. 问题是我需要首先检查主体,进行一些初始处理,然后确定是否将请求通过管道传输到远程服务器上。 So I need to parse the body before piping. 所以我需要在管道之前解析身体。

Is there any way around this problem? 有没有解决这个问题的方法?

The issue is that with streams (like req ), once you've read it you can't reset it. 问题是使用流(如req ),一旦你读了它就无法重置它。

Because body-parser has read the stream already, piping it won't work because that will try to read the stream again (which at that point has been exhausted). 因为body-parser已经读取了流,所以管道它将无法工作,因为它将尝试再次读取流(此时已经用尽)。

A workaround would be take the text read by body-parser , and create a minimal req "clone" in order for request to be able to pass the request along: 解决方法是使用body-parser读取的文本,并创建一个最小的req “clone”,以便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]);

You should create your own middleware if the parser is causing the problem. 如果解析器导致问题,您应该创建自己的中间件。 In all honesty you may want to parse the body a different way than the body parser. 老实说,你可能想要以与身体解析器不同的方式解析身体。

Given the limited knowledge about what the rest of your project is doing you could create middleware to hook the body parser middleware and just send a clone of request. 鉴于对项目其余部分正在做什么的了解有限,您可以创建中间件来挂钩正文解析器中间件并发送请求的克隆。 This however is not very efficient but will work and may help point you in the right direction. 然而,这不是非常有效,但会起作用,可能有助于指明您正确的方向。

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]);

I have not tested the above code. 我还没有测试过上面的代码。

Need to send a huge large data via POST, I was getting Error: socket hang up / code: 'ECONNRESET'. 需要通过POST发送大量大数据,我收到错误:socket挂断/代码:'ECONNRESET'。 Was able to resolve it via increasing limit in body parser. 能够通过增加身体解析器的限制来解决它。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM