节点嵌套HTTPS请求

时间:2016-02-19 16:36:41

标签: javascript node.js api rest httprequest

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

我也试过使用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

2 个答案:

答案 0 :(得分:0)

好的,很难确保它在您的环境中正常工作,但如果我这样做,我可能会使用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
});

答案 1 :(得分:-1)

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!
    });
    /**/
});

我无法测试它,但希望你能得到这个想法。只需创建一个任务列表并使用“async”运行它。