【问题标题】:node-http-proxy POST request times outnode-http-proxy POST 请求超时
【发布时间】:2016-02-10 01:53:39
【问题描述】:

我正在使用 node-http-proxy 进行 POST 请求,如下所示:

route.js
---------

var express = require('express');
var httpProxy = require('http-proxy');
var bodyParser = require('body-parser');
var proxy = httpProxy.createProxyServer({secure:false});
var jsonParser = bodyParser.json();

proxy.on('proxyReq', function(proxyReq, req, res, options) {
    logger.debug("proxying for",req.url);
    //set headers
    logger.debug('proxy request forwarded succesfully');
});

proxy.on('error', function (err, req, res) {
  res.writeHead(500, {
    'Content-Type': 'text/plain'
  });
  res.end('Something went wrong. And we are reporting a custom error message.');
});

proxy.on('proxyRes', function (proxyRes, req, res) {
  console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2));
});

module.exports = function(app){
  app.post('/recording',jsonParser,function(req,res){
    // update request body
    proxy.web(req, res, { target: <<host>>:<<port>>});
  });
}

app.js
---------

var express = require('express');
var app = express();
 require('./routes')(app);

app.listen(8080);
console.log("Demo server running");

我也使用 bodyparser 中间件,它存在Gitbug issue 中提到的已知问题。所以我尝试将此行添加为 app.js 中的最后一行

app.use(require('connect-restreamer')());

但 POST 请求仍然挂起并最终失败。我该如何解决 ? bodyparser 有什么替代品吗?

【问题讨论】:

  • app.js 中的 app 实例与 routes.js 中的实例是否相同?
  • @KevinReilly 是的,它是同一个实例。我从 app.js 本身传递它,并用实际来源更新了问题

标签: node.js proxy node-http-proxy body-parser


【解决方案1】:

尝试颠倒 bodyParser- 和代理中间件的顺序:

module.exports = function(app){
  app.post('/recording', function(req,res){
    // update request body
    proxy.web(req, res, { target: <<host>>:<<port>>});
  }, jsonParser);
}

认为这个问题类似于:socket hang up error with nodejs

【讨论】:

  • 当我收到“/recording”的 POST 请求时,我需要从请求正文中解析 JSON,然后将其代理到另一台服务器。当我在代理之后移动中间件时,我无法从初始请求中提取 JSON,因为它说未定义。
  • 在这种情况下,您可能必须使用github.com/dominictarr/connect-restreamer 来恢复流;因为 bodyParser 把它们弄乱了。
【解决方案2】:

稍微扩展一下,这里发生的事情是节点请求是一个流,它只能被读取一次,然后消费流数据。

当您在 express 中使用 body-parser 中间件时,它会消耗请求流主体 - 如果您尝试在此之后代理请求,则没有要发送的主体流,因此代理的另一端会收到一个带有内容长度等...但无限期地等待接收永远不会到达的 POST 正文。

如果您想代理 POST/PUT 或任何包含正文的请求,您必须在任何中间件使用正文之前 这样做。这就是上面@chimmurai 回答有效的原因。

另外,请注意,出于同样的原因,代理请求后执行的中间件也会受到同样的影响,一旦请求流被消耗,后续中间件将不会读取任何内容。这就是 connect-restreamer 之类的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    相关资源
    最近更新 更多