【问题标题】:proxy json requests with node express使用 node express 代理 json 请求
【发布时间】:2014-11-25 03:22:21
【问题描述】:

我使用以下 node-express 代码将请求从 Web 服务器代理到 API 服务器:

app.use('/api', function(req, res) {
  var url = 'http://my.domain.com/api' + req.url;
  req.pipe(request(url)).pipe(res);
});

这适用于任何动词的简单请求(get、post 等),但是一旦我发送 'Content-type': 'application/json' 请求,它就会挂在 pipe 行。

为什么这个简单的 node-express 代理代码会挂在 json 请求上?
如何更改它以支持它们?

【问题讨论】:

  • 您是否在已经读取所有请求数据的路由之前使用了正文解析中间件?
  • @mscdex 我正在处理angular-fullstack yeoman generated project。看到项目uses the body-parser package,所以答案大概是yes
  • 尝试在正文解析中间件之前移动您的自定义中间件(甚至将其作为第一个中间件),看看是否有帮助。
  • @mscdex 谢谢!注释掉the two lines using body-parser 就行了,但我宁愿继续使用它。我不太确定如何“移动我的中间件”,我在上面的 routes.js 中设置了我的代理代码。另外,我认为您可以添加您的 cmets 作为答案,一旦我们解决了这个问题,我会接受它。
  • @mscdex 还有,你能解释一下为什么body-parser 挂起代理吗?

标签: json node.js express proxy


【解决方案1】:

app.use('/api', function(req, res) {
  var url = 'http://my.domain.com/api' + req.url;
  
  request({
          uri: url,
          method: "POST",
          body: _body,
          json: true
      }, function (_err, _res, _resBody) {
          //do somethings
          res.json(_resBody);
      });

});

【讨论】:

  • 你应该解释为什么你的代码是一个改进。
【解决方案2】:

在发布请求的情况下,以下构造起作用:

app.post('/api/method', (req, res) => {
  req.pipe(request.post(someUrl, { json: true, body: req.body }), { end: false }).pipe(res);
}

如果您使用的是 bodyparser 中间件,这当然是相关的。

【讨论】:

  • 这正是我想要的。发布一些 JSON,通过 express 代理它,从 API 返回响应。太棒了!
【解决方案3】:

您需要移动该自定义中间件函数之前 this line,以便它在任何正文解析器之前执行。这可以确保请求数据仍然存在,以便在您的自定义中间件中通过管道传输到 request(url)

目前挂起的原因是req没有数据要写入request(url)(因为body解析中间件已经读取了所有请求数据并解析了),所以它从不调用.end() request(url) 流。这意味着对url 的请求永远不会完成,因为它只是坐在那里等待它永远不会得到的数据。

【讨论】:

  • 在我看来,抛出错误会是更好的设计。我还希望body-parser 只解析数据而不是从req 中提取数据
  • 好吧,为了解析请求,它必须从请求流中读取数据。一旦读取了所有请求数据,它就消失了。使用streams2,我猜你可能能够将所有数据移回请求流,但这意味着你必须缓冲所有这些,如果有人上传了一个巨大的文件,这可能会很成问题.
  • 那么有两个问题:1)body-parser 是否允许访问已解析的 json?我可以将其重新流式传输到request(url) 吗? 2)routes is called after express 可能是有原因的,它是什么?如果是这样,我真的应该先代理,然后再处理然后路由吗?!代理不应该是本地处理后路由的一部分吗?
  • 1) body-parser 将其解析结果设置在req.body 下,因此您可以只使用JSON.stringify() 并将其写入您的出站请求。 2) Express 在收到请求时按顺序评估所有中间件和路由。在这种特殊情况下,config/express 仅添加了一堆中间件(用于处理正文、cookie 和会话解析、静态文件服务等),这些中间件会被执行首先在任何路由之前,以便路由可以获取解析的正文内容等。例如,如果您的自定义 /api 中间件需要有效的会话,您将必须修改堆栈顺序以满足您的需求。
  • 您的评论中的建议 1 对我有用。谢谢。 :)
猜你喜欢
  • 2012-09-24
  • 2020-12-20
  • 2014-12-29
  • 2017-08-27
  • 2019-02-07
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多