问题
I need to call 3rd party api from backend in NodeJS and return the data to ajax call in frontend
Below is my code:
router.post('/get_data', function(request, response){
var city_name = request.body.city_name;
if(city_name in city_name_done){
}
else {
city_name_done.push(city_name);
console.log('city_name: ' + city_name);
var options = {
host : 'api.openweathermap.org',
path : '/data/2.5/forecast/daily?q=' + city_name + '&mode=json&units=metric&cnt=14&appid=75e843de569fb57a783c2e73fd9a7bb5',
method : 'GET'
}
var maybe = '';
console.log('till here')
var req = http.request(options, function(res){
var body = "";
res.on('data', function(data) {
console.log('data came');
body += data;
});
res.on('end', function() {
console.log('ended too');
maybe = JSON.parse(body);
console.log(maybe.city);
});
});
console.log('here too man');
req.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
response.send(maybe);
}
});
I am able to get the city_name parameter from ajax post request from frontend side however I get 500 internal server error everytime I execute the post request
PS: Pardon my English and even the level of the question as I am an absolute beginner in NodeJS
回答1:
You are returning response from outside of function call that gets data from 3rd party api. You need to return response from res.on('end'
section. It is because api call is asynchronous and we have to wait for response to come.
res.on('end', function() {
console.log('ended too');
maybe = JSON.parse(body);
console.log(maybe.city);
response.send(maybe);
});
Complete code is
router.post('/get_data', function(request, response){
var city_name = request.body.city_name;
if(city_name in city_name_done){
}
else {
city_name_done.push(city_name);
console.log('city_name: ' + city_name);
var options = {
host : 'api.openweathermap.org',
path : '/data/2.5/forecast/daily?q=' + city_name + '&mode=json&units=metric&cnt=14&appid=75e843de569fb57a783c2e73fd9a7bb5',
method : 'GET'
}
var maybe = '';
console.log('till here')
var req = http.request(options, function(res){
var body = "";
res.on('data', function(data) {
console.log('data came');
body += data;
});
res.on('end', function() {
console.log('ended too');
maybe = JSON.parse(body);
console.log(maybe.city);
response.send(maybe);
});
});
console.log('here too man');
req.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
res.end();
}
});
回答2:
Well doing a simple 'GET' with Postman to api.openweathermap.org/data/2.5/forecast/daily?q=Miami&mode=json&units=metric&cnt=14&appid=75e843de569fb57a783c2e73fd9a7bb5
does return results.
So it seems like you may be missing something like var http = require('http');
maybe :)
回答3:
I strongly recommend to use the request
module in npm
, makes requests way easier to handle. See this.
Firstly: maybe
is not necessary here. You get a JSON
string from the API, then you parse it into an object, but when you send it, you need to stringify it, yet again. So just stick with the incoming data in the string form.
Secondly: response.send
is called outside of the end
event: so what is happening is that - JavaScript being asynchronous - it will call the API, but not wait for the response to come back, because you are yourself already sending a response to your client. You need to put that into the end
callback, in order to actually wait for the API.
So this is what I'd do:
router.post('/get_data', function(request, response){
var city_name = request.body.city_name;
if(city_name in city_name_done){
return;
}
else {
city_name_done.push(city_name);
console.log('city_name: ' + city_name);
var options = {
host : 'api.openweathermap.org',
path : '/data/2.5/forecast/daily?q=' + city_name + '&mode=json&units=metric&cnt=14&appid=75e843de569fb57a783c2e73fd9a7bb5',
method : 'GET'
}
console.log('till here')
var req = http.request(options, function(res){
var body = "";
res.on('data', function(data) {
console.log('data came');
body += data;
});
res.on('end', function() {
console.log('ended too');
console.log(maybe.city);
response.send(body);
});
});
console.log('here too man');
req.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
}
});
来源:https://stackoverflow.com/questions/38033751/nodejs-third-party-api-call-from-app-js