【问题标题】:node express/request: piping a POST request with body parsingnode express/request:使用正文解析管道发送 POST 请求
【发布时间】:2017-11-17 22:29:46
【问题描述】:

我正在尝试通过管道传输请求以供远程服务器处理,具体如下:

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 请求进行任何处理都会导致问题。事实上,当我删除解析器时,管道似乎工作正常。

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

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

【问题讨论】:

    标签: javascript node.js express node-request


    【解决方案1】:

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

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

    【讨论】:

    • 这如何回答这个问题?请确保您的回答与所提出的问题有关。
    【解决方案2】:

    问题在于,对于流(如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]);
    

    【讨论】:

    • 向大师学习!天才!不仅是一个很好的解决方案,而且还清晰简洁地解释了问题发生的原因。你确实是大师@robertklep!
    • ...只有一件事...应该是request.post(url) 而不仅仅是request(url)
    • 我很确定request 将使用req.method/stream.method 来确定要执行的请求类型,因此您不必明确说明。
    • 我似乎无法使用 in-stream(6.14 版本的节点,我可以使用另一个 3rd 方代替吗?还有其他选择吗?)
    • @OmriShneor into stream 是 npm 上的一个包 npmjs.com/package/into-stream
    【解决方案3】:

    如果解析器导致问题,您应该创建自己的中间件。老实说,您可能希望以与正文解析器不同的方式解析正文。

    鉴于您对项目的其余部分所做的了解有限,您可以创建中间件来挂钩主体解析器中间件并发送请求的克隆。然而,这不是很有效,但会起作用,并且可能有助于为您指明正确的方向。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-12
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-03
      • 2021-01-19
      • 2015-05-31
      相关资源
      最近更新 更多