【问题标题】:Node Nested HTTPS Request节点嵌套 HTTPS 请求
【发布时间】:2016-02-19 16:36:41
【问题描述】:

我正在编写一个节点脚本来发出多个 HTTPS 请求。第二次调用依赖于第一次调用 uri 参数。我可以使用节点请求模块从第一次调用中检索数据。但坚持第二次调用,因为我需要将 uri 参数从第一次调用传递到第二个 url。目标是在第一次调用时获取所有服务器并在第二次调用时获取服务器属性,直到我遍历所有用户。

我也尝试过使用 Promise,但是当我必须拨打第二个电话时卡住了。

请提供工作示例。

这是我的代码:

/**********************************************************************
DEPENDCIES MODULES
***********************************************************************/
var express = require('express');
var request = require('request');

var app = express(); 

/*************************************************************************
SOLUTION
*************************************************************************/
var username = '123',
    password = 'password*',
    role = 'Read-Only',
    url_host = 'https://link.com:1000' 

var url1 = url_host + '/type/PropertySetClasses/SystemObject/Servers/?username=' + username +  '&password=' + password + '&role=' + role;
var url2 = url_host + server_id[i] + '?username=' + username +  '&password=' + password + '&role=' + role;


var auth = "Basic " + new Buffer(username + ':' + password).toString("base64");

if ('development' == app.get('env')) {
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
}

request.get(
    {
        url: url1,
        headers: {
        'Authorization': auth,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
        }
    },
    // FETCH ALL SERVERS
    function (error, response, body) {
        if(!error && response.statusCode == 200) {
        var servers = JSON.parse(body);
        servers = servers.PropertySetClassChildrenResponse.PropertySetClassChildren.PropertySetInstances.Elements;

        // console.log(JSON.stringify(servers));

        var server_id = [];
        var result = servers.map(function(server) {
            servers = server.uri;
            server_id.push(servers);
        });
        // console.log(JSON.stringify(server_id));
        }
    }

); // END REQUEST

【问题讨论】:

  • var url2 = url_host + id_array[i] ...这个“id_array”是指“server_id”吗?并且您想异步获取和处理“server_id”,对吗?
  • 对不起。是的,它指的是 server_id。刚刚编辑了代码。
  • 是的,异步的。目前,我只想完成获取服务器属性。这是我的最终目标。
  • 我在这里只看到一个请求(最初的request.get() 调用)。您在哪里向其他服务器发出请求?另外,您是否有意多次覆盖您的服务器变量,包括在.map() 函数中?
  • @paul 我还没有,因为我不确定要采取哪些步骤。这就是我卡住的地方。我不知道我是否需要发出嵌套请求或另一个 get 请求。

标签: javascript node.js api rest httprequest


【解决方案1】:

好的,很难确保它在您的环境中正常工作,但如果我这样做,我可能会使用async 库。一旦你拥有servers 的(我假设是数组),你可以使用 async 并行或串行发送多个请求,具体取决于你想要获得的内容:

function getServerInfo(server, callback){
  var url = // build the URL to the current server, it wasn't clear to me how you were doing that either

  var options = {
        url: url,
        headers: {
        'Authorization': auth,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
        }
    }
    request.get(options, function(e,res,body){
      if(e) return callback(e);
      var json = JSON.parse(body); // probably do a try..catch just in case
      return callback(null, json);
    }

}

async.map(servers, getServerInfo, function (err, results){
  // results here is now an array of the data called back on each getServerInfo call
});

【讨论】:

    【解决方案2】:
    var express = require('express');
    var request = require('request');
    
    var async = require('async');
    // npm install async
    
    var app = express();
    
    var username = '123',
        password = 'password*',
        role = 'Read-Only',
        url_host = 'https://link.com:1000' 
    
    if ('development' == app.get('env')) {
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    }
    
    
    function doRequest(params, callback)
    {
        request.get(params, function(error, response, body)
        {
            if (error || response.statusCode !== 200)
            {
                callback({error: error, statusCode: response.statusCode});
                return; // [!] break
            }
    
            callback(null, response, body);
            // export
        });
    
    }
    
    var url = url_host + '/type/PropertySetClasses/SystemObject/Servers/?username=' + username +  '&password=' + password + '&role=' + role;
    var auth = "Basic " + new Buffer(username + ':' + password).toString("base64");
    
    var requestParams = {
        url: url,
        headers: {
        'Authorization': auth,
        'Content-Type': 'application/json',
        'Accept': 'application/json'
        }
    };
    
    // FETCH SERVER LIST
    doRequest(requestParams, function(err, response, body)
    {
        if (err) {
            throw new Error('unable to fetch server data: ' + JSON.stringify(err));
        }
    
        var servers = JSON.parse(body);
            servers = servers.PropertySetClassChildrenResponse.PropertySetClassChildren.PropertySetInstances.Elements;
    
        var server_ids = [];
        var result = servers.map(function(server)
        {
            // servers = server.uri; // ??? why
    
            /**
             * merge all "server ids" here somehow
             */
            server_ids.push(server.uri);
        });
    
        var tasks = [];
        // async work chain
    
        var results = {};
        // response obj.
    
        server_ids.forEach(function(server_id)
        {
            tasks.push(function(next)
            {
                var params = JSON.parse(JSON.stringify(requestParams));
                // clone | extend main params.
    
                params.url = url_host + server_id + '?username=' + username 
                    + '&password=' + password + '&role=' + role;
    
                doRequest(params, function(err, response, body)
                {
                    if (!err)
                    {
                        results[server_id] = {response: response, body: body};
                        // || arguments
                    }
                    else {
                        next([server_id, err]);
                    }
                });
            });
        });
    
        // https://github.com/caolan/async#waterfalltasks-callback
        async.waterfall(tasks, function(err)
        {
            if (err) {
                throw new Error('the server with Id: ' + err[0] + ' failed with error: ' + JSON.stringify(err[1]));
            }
    
            console.log(results);
            // all done!
        });
    
        /**
        // https://github.com/caolan/async#parallel
        async.parallel(tasks, function(err)
        {
            if (err) {
                throw new Error('the server with Id: ' + err[0] + ' failed with error: ' + JSON.stringify(err[1]));
            }
    
            console.log(results);
            // all done!
        });
        /**/
    
        /**
        // https://github.com/caolan/async#parallel
        async.parallelLimit(tasks, 10, function(err)
        {
            if (err) {
                throw new Error('the server with Id: ' + err[0] + ' failed with error: ' + JSON.stringify(err[1]));
            }
    
            console.log(results);
            // all done!
        });
        /**/
    });
    

    我无法对其进行测试,但希望您能理解。只需创建一个任务列表并使用“异步”运行它。

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 2018-06-04
      • 2020-03-27
      相关资源
      最近更新 更多