Виклик JSON API за допомогою Node.js


79

Я намагаюся отримати фотографію профілю 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)

Відповіді:


146

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);
});

Аргумент res насправді є об’єктом http.IncomingMessage . З того, що я можу зібрати, клас ClientResponse був реконструйований з бібліотеки http вузла.
dmur

модуль запитів подбає про простий http get / post / і т. д. для вас github.com/request/request
Hayashi

2
Ого, це нижчий рівень, ніж я очікував би від стандартної бібліотеки в наші дні.
elsurudo

3
JSON.parse()викидає винятки з недійсного JSON і завжди повинен викликатися всередині try/catchблоку, інакше вся програма може зірватися з недійсними даними (що іноді трапляється).
rsp

Щоб уникнути необхідності робити try/catchfor JSON.parse(що завжди слід робити, якщо ви використовуєте JSON.parse- див. Цю відповідь ), ви можете використовувати такий модуль, requestякий може автоматично проаналізувати JSON для вас, як я показав у своїй відповіді нижче.
rsp

44

Проблеми з іншими відповідями:

  • небезпечний JSON.parse
  • відсутність перевірки коду відповіді

Всі відповіді тут використовують JSON.parse()в небезпечним способом . Ви завжди повинні поміщати всі дзвінки JSON.parse()в try/catchблок, особливо , коли ви розбираєте JSON , що виходить від зовнішнього джерела, як ви робите тут.

Ви можете використовувати requestдля автоматичного синтаксичного аналізу JSON, про що тут не згадувалося в інших відповідях. Відповідь вже використовується за допомогою requestмодуля, але він використовує JSON.parse()для синтаксичного аналізу JSON вручну - який завжди повинен запускатися всередині try {} catch {}блоку для обробки помилок неправильного JSON, інакше вся програма вийде з ладу. І трапляється неправильний JSON, повірте мені.

Інші відповіді, які httpтакож використовуються, використовуються JSON.parse()без перевірки на винятки, які можуть трапитись і призвести до збоїв у роботі програми.

Нижче я покажу кілька способів безпечного впорання з цим.

У всіх прикладах використовується загальнодоступний GitHub API, тому кожен може спробувати цей код безпечно.

Приклад з 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.


17

Я думаю, що для простих 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)
  }
})

9

Я використовую get-json, дуже простий у використанні:

$ npm install get-json --save

Імпорт get-json

var getJSON = require('get-json')

Щоб зробити GETзапит, ви зробите щось на зразок:

getJSON('http://api.listenparadise.org', function(error, response){
    console.log(response);
})

1

Іншим рішенням є користувач axios :

npm install axios

Код буде таким:

const url = `${this.env.someMicroservice.address}/v1/my-end-point`;

const { data } = await axios.get<MyInterface>(url, {
  auth: {
    username: this.env.auth.user,
    password: this.env.auth.pass
  }
});

return data;

0

Бібліотека Unirest значно спрощує це. Якщо ви хочете використовувати його, вам потрібно встановити 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)
    }
  })
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.