NodeJS API使嵌套http获取请求并返回响应

问题描述:

我有一个NodeJS API。 API中的逻辑需要向google.com发出http获取请求,捕获google.com的响应,然后将html响应返回到原始API调用。我的问题是异步捕获谷歌的http响应并将其返回到原始API调用。NodeJS API使嵌套http获取请求并返回响应

// Entry point to /api/specialday 
module.exports = function(apiReq, apiRes, apiNext) { 
    var options = { 
    host: 'www.google.com' 
    }; 

    callback = function(googleRes) { 
    var str = ''; 

    // another chunk of data has been recieved, so append it to `str` 
    googleRes.on('data', function (chunk) { 
     str += chunk; 
    }); 

    // capture the google response and relay it to the original api call. 
    googleRes.on('end', function() {   
     apiRes.send(str); 
    }); 
    } 

    http.request(options, callback).end(); 
} 

我在这里得到的错误是Uncaught TypeError: Cannot read property 'send' of undefined。我明白为什么我会收到错误(因为apiRes超出范围),我无法弄清楚如何正确执行。任何帮助非常感谢!

您看到上述错误的原因是因为原始响应对象apiRes在您收到来自Google API的响应时已消失。

至于我可以告诉你将不得不bind()apiRes两次(未经测试):

callback = function(googleRes) { 
    var str = ''; 

    // another chunk of data has been recieved, so append it to `str` 
    googleRes.on('data', function (chunk) { 
    str += chunk; 
    }); 

    // capture the google response and relay it to the original api call. 
    googleRes.on('end', function() {   
    apiRes.send(str); 
    }.bind(apiRes)); 

}.bind(apiRes) 

一个更现代的解决办法是使用承诺为这项任务https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise

承诺,这就是它!谢谢Michal。以下是我的实现的简化版本。

// Entry point to /api/specialday 
module.exports = function(apiReq, apiRes, apiNext) { 

    var p1 = new Promise(
    // The resolver function is called with the ability to resolve or 
    // reject the promise 
    function(resolve, reject) { 

     var options = { 
     host: 'www.google.com' 
     }; 

     callback = function(googleRes) { 
     var str = ''; 

     // another chunk of data has been recieved, so append it to `str` 
     googleRes.on('data', function (chunk) { 
      str += chunk; 
     }); 

     // capture the google response and relay it to the original api call. 
     googleRes.on('end', function() {   
      resolve(str); 
     }); 
     } 

     http.request(options, callback).end(); 
)}; 

    p1.then(function(googleHtml) { 
    apiRes.status(200).send(googleHtml); 
    } 
} 

然后我可以运行我的应用程序,并调用使用邮差的API在http://localhost:8080/api/gains:使用要求

直接与apiRes管输出,采样:

var request = require("request"); 

// Entry point to /api/specialday 
module.exports = function(apiReq, apiRes, apiNext) { 
    request.get('http://www.google.fr').pipe(apiRes); 
});