Подтвердить что ты не робот

Вызов 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)
4b9b3361

Ответ 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)
    }
  })