如何在nodejs中将api请求写入另一个api请求

时间:2017-02-28 10:22:34

标签: javascript node.js google-maps-api-3

我有一个问题。我正在使用node.js,我想做一个api调用,这取决于另一个api响应。我不知道。我试图做一些事情,但我遇到了一些错误:

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
    at ServerResponse.header (C:\workstation\node_modules\express\lib\respons
e.js:719:10)
    at ServerResponse.send (C:\workstation\node_modules\express\lib\response.
js:164:12)
    at ServerResponse.json (C:\workstation\node_modules\express\lib\response.
js:250:15)
    at IncomingMessage.<anonymous> (C:\workstation\server\controllers\apicontroller.js:81:25)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

明确地说,这就是我想要做的: 1 - 调用api以检索包含经度和纬度坐标的响应 2 - 然后通过使用google api对它们进行地理编码,将它们翻译成可读的地址。 3 - 最后在前端显示可读地址。

这是我的代码:

var https = require('https');
var Client = require('node-rest-client').Client;
var client = new Client();


module.exports.getaddresses = function(request,response){

 var optionsget = {
        host : 'externalhost',
        port : 443,
        path : '/rest/of/the/api', 
        method: 'GET', 
        auth: 'login:pwd'
    };
    var reqGet = https.request(optionsget, function(res){
        var myData = '';

        res.on('data', function(d){
            myData += d;
        });

        res.on('end', function(){
            var str = JSON.parse(myData);

            var locations = [];
            var lat, lon, address;
            for (var i=0;i<=str.reports.length-1;i++){

               lat = str.reports[i].latitude;
               lon = str.reports[i].longitude;

                var args = {
                    data: { lat: lat,lon: lon},
                    headers: { "Content-Type": "application/json" }
                    };
                client.post("http://localhost:3100/api/geocode", args, function (data, myresponse) {
                    locations.push({
                    long:str.reports[i].longitude,
                    latitude:str.reports[i].latitude,             
                    timestamp:str.reports[i].locationts,
                    address:address
                })

                });
               response.json(locations);
               }})
               });

    reqGet.end();
    reqGet.on('error', function(e){
        console.error("error:",e);
    });

}

有人能帮助我吗?

2 个答案:

答案 0 :(得分:1)

您会看到此错误,因为您要在for循环内发回响应,这意味着它会多次执行。每个请求处理程序只应返回一次响应。

您可以通过聚合位置并最终发回一次响应来解决此问题。

var https = require('https');
var Client = require('node-rest-client').Client;
var client = new Client();


module.exports.getaddresses = function (request, response) {

    var optionsget = {
        host: 'externalhost',
        port: 443,
        path: '/rest/of/the/api',
        method: 'GET',
        auth: 'login:pwd'
    };
    var reqGet = https.request(optionsget, function (res) {
        var myData = '';

        res.on('data', function (d) {
            myData += d;
        });

        res.on('end', function () {
            var str = JSON.parse(myData);

            var locations = [];
            var lat, lon, address;
            for (var i = 0; i <= str.reports.length - 1; i++) {

                lat = str.reports[i].latitude;
                lon = str.reports[i].longitude;

                var args = {
                    data: { lat: lat, lon: lon },
                    headers: { "Content-Type": "application/json" }
                };
                client.post("http://localhost:3100/api/geocode", args, function (data, myresponse) {
                    locations.push({
                        long: str.reports[i].longitude,
                        latitude: str.reports[i].latitude,
                        timestamp: str.reports[i].locationts,
                        address: address
                    })

                });
            }
        })
    });

    reqGet.end();
    reqGet.on('error', function (e) {
        console.error("error:", e);
    });

    response.json(locations);
}

请注意,唯一的变化是将行response.json(locations)移到for循环之外。

答案 1 :(得分:0)

我注意到在这个URL中,你也在调用项目中的端点。为什么不直接调用函数?

            client.post("http://localhost:3100/api/geocode", args, function (data, myresponse) {
                locations.push({
                long:str.reports[i].longitude,
                latitude:str.reports[i].latitude,             
                timestamp:str.reports[i].locationts,
                address:address
            })

相反,做这样的事情,

res.on('end', function () {
        var str = JSON.parse(myData);

        var locations = [];
        var lat, lon, address;
        for (var i = 0; i <= str.reports.length - 1; i++) {

            lat = str.reports[i].latitude;
            lon = str.reports[i].longitude;

            var args = {
                data: { lat: lat, lon: lon },
                headers: { "Content-Type": "application/json" }
            };

            somePostGeoCodeFunction(*Your params to pass*);     

            });
        }
    })