Вызов API JSON с Node.js
Я пытаюсь получить изображение профиля facebook пользователя, зарегистрированного в моем приложении. API Facebook утверждает, что http://graph.facebook.com/517267866/?fields=picture
возвращает правильный URL как объект JSON.
Я хочу получить URL-адрес изображения из моего кода. Я попробовал следующее, но здесь что-то не хватает.
var url = 'http://graph.facebook.com/517267866/?fields=picture';
http.get(url, function(res) {
var fbResponse = JSON.parse(res)
console.log("Got response: " + fbResponse.picture);
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
Запуск этого кода приводит к следующему:
undefined:1
^
SyntaxError: Unexpected token o
at Object.parse (native)
Ответы
Ответ 1
Аргумент res
в обратном вызове http.get()
- это не тело, а объект http.ClientResponse. Вам нужно собрать тело:
var url = 'http://graph.facebook.com/517267866/?fields=picture';
http.get(url, function(res){
var body = '';
res.on('data', function(chunk){
body += chunk;
});
res.on('end', function(){
var fbResponse = JSON.parse(body);
console.log("Got a response: ", fbResponse.picture);
});
}).on('error', function(e){
console.log("Got an error: ", e);
});
Ответ 2
Проблемы с другими ответами:
- небезопасно
JSON.parse
- проверка кода ответа
Все ответы здесь используют JSON.parse()
в небезопасном виде.
Вы всегда должны помещать все вызовы JSON.parse()
в блок try/catch
особенно, когда вы разбираете JSON, исходящий из внешнего источника, например, вы здесь.
Вы можете использовать request
для автоматического анализа JSON, который не упоминался здесь в других ответах. Уже существует ответ с использованием модуля request
, но он использует JSON.parse()
для ручного анализа JSON - который должен всегда выполняться внутри блока try {} catch {}
для обработки ошибок неправильного JSON или иначе всего приложения сбой. И неправильный JSON случается, поверьте мне.
Другие ответы, которые используют http
, также используют JSON.parse()
, не проверяя исключения, которые могут произойти, и сбой вашего приложения.
Ниже я покажу несколько способов безопасно справиться с этим.
Все примеры используют публичный API GitHub, чтобы каждый мог безопасно выполнить этот код.
Пример с request
Вот рабочий пример с request
, который автоматически анализирует JSON:
'use strict';
var request = require('request');
var url = 'https://api.github.com/users/rsp';
request.get({
url: url,
json: true,
headers: {'User-Agent': 'request'}
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
} else if (res.statusCode !== 200) {
console.log('Status:', res.statusCode);
} else {
// data is already parsed as JSON:
console.log(data.html_url);
}
});
Пример с http
и try/catch
Это использует https
- просто измените https
на http
, если вы хотите HTTP-соединения:
'use strict';
var https = require('https');
var options = {
host: 'api.github.com',
path: '/users/rsp',
headers: {'User-Agent': 'request'}
};
https.get(options, function (res) {
var json = '';
res.on('data', function (chunk) {
json += chunk;
});
res.on('end', function () {
if (res.statusCode === 200) {
try {
var data = JSON.parse(json);
// data is available here:
console.log(data.html_url);
} catch (e) {
console.log('Error parsing JSON!');
}
} else {
console.log('Status:', res.statusCode);
}
});
}).on('error', function (err) {
console.log('Error:', err);
});
Пример с http
и tryjson
Этот пример аналогичен приведенному выше, но использует модуль tryjson
. (Отказ от ответственности: я являюсь автором этого модуля.)
'use strict';
var https = require('https');
var tryjson = require('tryjson');
var options = {
host: 'api.github.com',
path: '/users/rsp',
headers: {'User-Agent': 'request'}
};
https.get(options, function (res) {
var json = '';
res.on('data', function (chunk) {
json += chunk;
});
res.on('end', function () {
if (res.statusCode === 200) {
var data = tryjson.parse(json);
console.log(data ? data.html_url : 'Error parsing JSON!');
} else {
console.log('Status:', res.statusCode);
}
});
}).on('error', function (err) {
console.log('Error:', err);
});
Резюме
Пример, который использует request
, является самым простым. Но если по какой-то причине вы не хотите его использовать, не забудьте всегда проверять код ответа и безопасно разбирать JSON.
Ответ 3
Я думаю, что для простых HTTP-запросов, подобных этому, лучше использовать модуль request
. Вам нужно установить его с помощью npm (npm install request
), а затем ваш код может выглядеть так:
const request = require('request')
,url = 'http://graph.facebook.com/517267866/?fields=picture'
request(url, (error, response, body)=> {
if (!error && response.statusCode === 200) {
const fbResponse = JSON.parse(body)
console.log("Got a response: ", fbResponse.picture)
} else {
console.log("Got an error: ", error, ", status code: ", response.statusCode)
}
})
Ответ 4
Unirest library упрощает это. Если вы хотите его использовать, вам нужно установить пакет unirest
npm. Тогда ваш код может выглядеть так:
unirest.get("http://graph.facebook.com/517267866/?fields=picture")
.send()
.end(response=> {
if (response.ok) {
console.log("Got a response: ", response.body.picture)
} else {
console.log("Got an error: ", response.error)
}
})