节点快递/请求:通过正文parsing来pipe理POST请求

我试图通过远程服务器pipe理一个请求,如下所示:

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

这对GET请求很好。 但是对于POST请求,我正在挣扎。 重要的一点是,我认为,对于POST请求,我在POST路由处理程序之前使用了一个主体parsing器,以便从POST请求中提取主体…这只是一个基本的文本主体parsing器,因为主体包含纯文本:

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

从这个问题和这个问题在我看来,做任何处理的POST请求之前,你pipe它会导致一个问题。 事实上,当我删除parsing器时,pipe道似乎工作正常。

问题是我需要首先检查一下机体,做一些初始化处理,然后决定是否将请求传送到远程服务器上。 所以我需要在pipe道之前parsing身体。

有没有办法解决这个问题?

问题是,stream(如req ),一旦你阅读它,你不能重置它。

由于body-parser已经读取了stream,所以pipe道将无法工作,因为它会尝试再次读取stream(在这一点上已经耗尽)。

解决方法是采用body-parser读取的文本,并创build一个最小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]); 

如果parsing器导致问题,您应该创build自己的中间件。 诚实地说,你可能想要以不同于身体parsing器的方式parsing身体。

考虑到你的项目的其他部分在做什么的知识有限,你可以创build中间件来钩住正文parsing器中间件,并发送一个请求的克隆。 然而,这不是非常有效,但将工作,并可能有助于指引你在正确的方向。

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

我还没有testing过上面的代码。