节点嵌套 HTTPS 请求
Node Nested HTTPS Request
我正在编写一个节点脚本来发出多个 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
好的,很难确保它在您的环境中正常工作,但如果我这样做,我可能会使用 async
库。一旦你有了 servers
的(我假设数组),你可以使用异步发送多个并行或串行的请求,这取决于你想要得到什么:
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
});
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"。
我正在编写一个节点脚本来发出多个 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
好的,很难确保它在您的环境中正常工作,但如果我这样做,我可能会使用 async
库。一旦你有了 servers
的(我假设数组),你可以使用异步发送多个并行或串行的请求,这取决于你想要得到什么:
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
});
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"。