nodejs中有两个HTTP请求问题

时间:2015-12-04 15:18:35

标签: javascript node.js amazon-web-services amazon-s3

我在Amazon Lambda上创建了一个函数。我的情况是我必须在两个不同的URL上同时发送两个HTTP请求。所以我在我的代码中用不同的URL写了两个HTTP请求。问题是大部分时间没有调用第一个HTTP请求,第二个HTTP请求几乎一直在运行。所以请帮我弄清楚问题所在。这是我的代码

console.log('Loading function');

var aws = require('aws-sdk');
var http = require('http');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = function(event, context) {
    console.log('Received event:', JSON.stringify(event, null, 2));

    // Get the object from the event and show its content type
    var bucket = event.Records[0].s3.bucket.name;
    var key = event.Records[0].s3.object.key;
    var params = {
        Bucket: bucket,
        Key: decodeURIComponent(key)
    };
   s3.getObject(params, function(err, data) {
        if (err) {
            console.log("Error getting object " + key + " from bucket " + bucket +
                ". Make sure they exist and your bucket is in the same region as this function.");
            context.fail("Error getting file: " + err);
        } else {
            var userString = JSON.stringify(params);
            console.log(userString);

            var options = {
              hostname: 'example1.com',
              path: '/api/test1.cfm',
              method: 'POST',
              Port:'80',
              headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Content-Length': userString.length
              }
            };
            console.log("Start");
            var x = http.request(options,function(res){
                console.log("Connected");
                console.log('CONTENT TYPE:', data.ContentType);
                console.log("Start");
                console.log("x");
                context.succeed(data.ContentType);

            });

            x.write(userString);
            x.end();



            var optionsdev = {
              hostname: 'example2.com',
              path: '/api/test2.cfm',
              method: 'POST',
              headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Content-Length': userString.length
              }
            };
            console.log("Start");
            var y = http.request(optionsdev,function(res){
                console.log("Connected");
                console.log('CONTENT TYPE:', data.ContentType);
                console.log("Start");
                console.log("y");
                context.succeed(data.ContentType);

            });

            y.write(userString);
            y.end();



        }
    });
};

1 个答案:

答案 0 :(得分:1)

首先,如果你看一下http.request()的node.js文档中的示例代码,你会得到一个回调,但是在那个回调中,你传递了一个响应对象,它是一个流,你必须设置事件处理程序。

以下是文档中的基本结构:

var req = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
  res.on('end', function() {
    console.log('No more data in response.')
  })
});

req.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

// write data to request body
req.write(postData);
req.end();

因此,您必须在收到“数据”时处理回复。并且'结束'响应对象上的事件。

对于大多数请求,这有点不方便,因为您必须累积响应,因为data事件可以被调用多个。我建议使用请求模块,因为它为您完成了更多的工作。

然后,其次,如果您希望一个接一个地连续处理您的操作,则需要在第一个操作完成之前不要启动第二个操作。有许多不同的方法来构造它,但最像你已经拥有的结构就是在完成第一个请求时启动第二个请求。

以下是使用request() module

执行此操作的方法
var aws = require('aws-sdk');
var http = require('http');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });
var request = require('request');

exports.handler = function(event, context) {
    console.log('Received event:', JSON.stringify(event, null, 2));

    // Get the object from the event and show its content type
    var bucket = event.Records[0].s3.bucket.name;
    var key = event.Records[0].s3.object.key;
    var params = {
        Bucket: bucket,
        Key: decodeURIComponent(key)
    };
   s3.getObject(params, function(err, data) {
        if (err) {
            console.log("Error getting object " + key + " from bucket " + bucket +
                ". Make sure they exist and your bucket is in the same region as this function.");
            context.fail("Error getting file: " + err);
        } else {
            var sendData = JSON.stringify(params);
            request.post('http://example1.com/api/test1.cfm', {form: sendData}, function(err, httpResponse, body) {
                if (err) {
                    console.log("Error on first post");
                } else {
                    // do something with the response here
                    console.log("first request = ", body);
                    // context.succeed(...);

                    // now launch the second request
                    request.post('http://example2.com/api/test2.cfm', {form: sendData}, function(err, httpResponse, body) {
                        if (err) {
                            console.log("Error on second post");
                        } else {
                            // do something with the response here
                            console.log("second request = ", body)
                            // context.succeed(...);

                            // done with both requests here

                        }
                    });
                }
            });
        }
    });
};