在 Node.js 中的单个 HTTP 请求中调用多个 HTTP 请求

Posted

技术标签:

【中文标题】在 Node.js 中的单个 HTTP 请求中调用多个 HTTP 请求【英文标题】:Calling multiple HTTP requests in a single HTTP request in Node.js 【发布时间】:2016-03-29 22:25:28 【问题描述】:

我正在尝试在单个 URL 调用中调用多个 URL,并将其 json 响应推送到一个数组中,然后将该数组发送给最终用户。

我的代码如下所示:

var express = require('express');

var main_router = express.Router();

var http = require('http');

urls = [
"http://localhost:3010/alm/build_tool",
"http://localhost:3010/alm/development_tool",
"http://localhost:3010/alm/project_architecture"];

var responses = [];

main_router.route('/')

.get(function (req, res) 

var completed_requests = 0;

for (url in urls) 

  http.get(url, function(res) 

    responses.push(res.body);

    completed_request++;

    if (completed_request == urls.length) 

        // All download done, process responses array
    
  );

res.send(responses);
);

我也尝试过使用 npm 请求模块。 当我运行这段代码时,它只返回 NULL 或一些只有标题的随机输出。

我的目标是在单个节点获取请求中调用多个 URL,并将其 JSON 输出附加到数组中并发送给最终用户。

谢谢

【问题讨论】:

你必须使用回调或者我可以建议异步模块github.com/caolan/async 见this answer。您实际上应该使用res.on('end', function... 等待响应结束 【参考方案1】:

来,试试这段代码,

const async = require('async');
const request = require('request');

function httpGet(url, callback) 
  const options = 
    url :  url,
    json : true
  ;
  request(options,
    function(err, res, body) 
      callback(err, body);
    
  );


const urls= [
  "http://localhost:3010/alm/build_tool",
  "http://localhost:3010/alm/development_tool",
  "http://localhost:3010/alm/project_architecture"
];

async.map(urls, httpGet, function (err, res)
  if (err) return console.log(err);
  console.log(res);
);

说明: 此代码使用async 和request 节点包。 async.map 根据定义需要 3 个参数,第一个是一个数组,第二个是您要使用该数组的每个元素调用的迭代器函数,以及在 async.map 完成处理时调用的回调函数。

map(arr, iterator, [callback])

通过将 arr 中的每个值映射到 迭代器函数。使用 arr 中的项目调用迭代器 以及完成处理时的回调。这些中的每一个 回调有 2 个参数:一个错误,以及转换后的项目 arr。如果迭代器将错误传递给其回调,则主回调 (对于 map 函数)立即调用错误。

注意:对迭代器函数的所有调用都是并行的。

在您的 httpGet 函数中,您使用传递的 url 调用 request 函数,并明确告知响应格式为 jsonrequest,处理完成后,调用回调函数,带三个参数,err - 如果有,res - 服务器响应,body - 响应正文。 如果request 中没有errasync.map 将这些回调的结果作为一个数组收集,并在最后将该数组传递给它的第三个回调函数。否则,如果 (err) 为真,async.map 函数将停止执行并使用 err 调用其回调。

【讨论】:

这里的request 是什么? async 怎么样?在答案中使用库很好,但前提是您指定要使用的库:P 好吧,asker 似乎已经知道这些包了。无论如何,为其他用户更新。 感谢您。是否可以将所有数据主体合并为一个?如果我从多个 URls i.imgur.com/nX1IRla.png 下载 JSON 格式,这就是我的样子。您知道如何将它们合并到 1 个数据体下吗? 您可以简单地遍历每个响应正文并将其添加到您的最终正文中。但是,如果您使用分页,请小心。【参考方案2】:

我建议使用async 库。

async.map(urls, http.get, function(err, responses)
  if (err)
    // handle error
  
  else 
    res.send responses
  
)

上面的 sn-p 将对每个 url 并行执行 http.get 调用,并在收到所有响应后使用所有调用的结果调用您的回调函数。

如果要串联调用url,可以使用async.mapSeries。如果你想限制并发请求的数量,你可以使用async.mapLimit

【讨论】:

感谢您的评论。如果您有任何可用的代码,请分享。我尝试了以下代码,但没有得到任何响应。 main_router.route('/') .get(function (req, res) var test = async.each(urls, http.get, function(err, response, callback) if (err) // 处理错误 else 返回响应; ) res.send(test); res.end(); ); 注意:async.each 回调不处理响应。如果您在调用结束时需要响应,您应该使用async.map,它将在您的回调函数中以数组的形式响应每个 HTTP 请求。

以上是关于在 Node.js 中的单个 HTTP 请求中调用多个 HTTP 请求的主要内容,如果未能解决你的问题,请参考以下文章

从 Node.JS 中的未捕获异常中恢复

从 Node.JS 中的未捕获异常中恢复

使用 node.js 运行许多并行 http 请求

如何从Google Cloud Function(Cheerio,Node.js)发出多个http请求

node.js 中的 Http 请求重定向和 cookie 处理

Node.js 中的 cURL 等效项?