Перебор json-фида Яндекс Фоток с помощью jQuery

В предыдущей статье, мы работали с xml-фидом Яндекс Фоток, а в этой разберемся как работать с json-представлением альбома фотографий, так как API Яндекс Фоток представляет два варианта обмена данными: xml и json. Для обработки-перебора json-фида мы будем использовать jQuery.

Необходимо сразу понять, что нам предстоит работа с json-файлом расположенным не на нашем сервере, а это означает, что стандартный вариант getJSON из jQuery нам не подойдет. В работе с JSON с удаленного сервера нам поможет JSONP («JSON with Padding») и $.ajax.

Для того, чтобы Яндекс Фотки отдали нам фид фотоальбома в формате JSON, нам необходимо в строку запроса добавить параметр format=json. Одновременно с этим, использование JSONP подразумевает наличие в URL указания функции обработки, - типа callback=funcName, но это нам не очень подходит и мы заменим это требование на более демократичный вариант указания коллбэка: callback=?

Полный и правильный адрес к фиду будет таков

http://api-fotki.yandex.ru/api/users/styleroom/album/156904/photos/?format=json&callback=?

Сам json-ответ сервера Яндекс Фоток будет выглядеть вот так

{
    "updated": "2016-05-28T18:48:03Z",
    "author": "styleroom",
    "links": {
            "self": "http:\/\/path-to\/album\/156904\/photos\/?format=json",
            "alternate": "http:\/\/path-to\/album\/156904\/"
    },
    "title": "Лядины",
    "authors": [{
            "name": "styleroom",
            "uid": "13223519"
    }],
    "entries": [{
            "edited": "2016-05-28T19:24:27Z",
            "updated": "2016-05-28T19:24:27Z",
            "xxx": false,
            "img": {
                    "XXS": {
                            "width": 75,
                            "href": "http:\/\/path-to_XXS",
                            "height": 75
                    },
                    "XL": {
                            "width": 673,
                            "href": "http:\/\/path-to_XL",
                            "height": 430
                    },
                    "M": {
                            "width": 300,
                            "href": "http:\/\/path-to_M",
                            "height": 192
                    },
                    "L": {
                            "width": 500,
                            "href": "http:\/\/path-to_L",
                            "height": 319
                    },
                    "XXXS": {
                            "width": 50,
                            "href": "http:\/\/path-to_XXXS",
                            "height": 50
                    },
                    "S": {
                            "width": 150,
                            "href": "http:\/\/path-to_S",
                            "height": 96
                    },
                    "XS": {
                            "width": 100,
                            "href": "http:\/\/path-to_XS",
                            "height": 64
                    },
                    "orig": {
                            "width": 673,
                            "href": "http:\/\/path-to_orig",
                            "bytesize": 79473,
                            "height": 430
                    }
            },
            "links": {
                    "album": "http:\/\/path-to\/album\/156904\/?format=json",
                    "editMedia": "http:\/\/path-to_orig",
                    "self": "http:\/\/path-to\/photo\/700434\/?format=json",
                    "alternate": "http:\/\/path-to\/view\/700434\/",
                    "edit": "http:\/\/path-to\/photo\/700434\/?format=json"
            },
            "tags": {
                    "внуки": "http:\/\/path-to\/tag\/%D0%B2%D0%BD%D1%83%D0%BA%D0%B8\/",
                    "бабушка": "http:\/\/path-to\/tag\/%D0%B1%D0%B0%D0%B1%D1%83%D1%88%D0%BA%D0%B0\/"
            },
            "title": "19.jpg",
            "summary": "Как их много!",
            "access": "public",
            "disableComments": false,
            "authors": [{
                    "name": "styleroom",
                    "uid": "13223519"
            }],
            "hideOriginal": false,
            "author": "styleroom",
            "id": "urn:yandex:fotki:styleroom:photo:700434",
            "published": "2016-05-27T05:45:14Z"
    }, {},..., {}],
    "id": "urn:yandex:fotki:styleroom:album:156904:photos",
    "imageCount": 27,
    "summary": "Каргополье, Архангельская область."
}

Наглядности ради, давайте попробуем продемонстрировать - что же мы получим от json-фида. Для этого создадим простенький код

$(document).ready(function(){
    // функция-обработчик json-данных
    function myFunc (data) {
        $.each(data, function(key,val){
            $('#qwe').append('Значение ключа '+key+' : '+val+"<hr>");
        });
    }    
    // низкоуровневый ajax-запрос
    $.ajax({
        url: "http://path-to/album/156904/photos/?format=json&callback=?",
        dataType: "jsonp",
        success: myFunc
    }); 
});

Результатом отработки этого кода будут такие строки в div с айдишником qwe.

Значение ключа updated : 2016-05-28T18:48:03Z
Значение ключа author : styleroom
Значение ключа links : [object Object]
Значение ключа title : Лядины
Значение ключа authors : [object Object]
Значение ключа entries : [object Object],[object Object],...,[object Object]
Значение ключа id : urn:yandex:fotki:styleroom:album:156904:photos
Значение ключа imageCount : 27
Значение ключа summary : Каргополье, Архангельская область

То есть знакомые нам по первой статье узлы станут объектами, доступ к значениям которых будет в точечной нотации. Вот так: ключ.свойство

С узлами-ключами updated, author, title, id, imageCount, summary все просто - для доступа к значениям необходимо использовать такую строку, где data - это аргумент из нашей функции myFunc

data.ключ // data.author, data-title, data.summary

Теперь осталось решить вопросы с ключами, у которых значениями являются объекты: links, authors и entries. Причем значениями authors, entries и authors внутри entries являются массивы, так как их значения начинаются с квадратных скобок.

В тренировочных целях, мы опять извлечем из фида следующие элементы:

об альбоме в целом

  1. ID альбома
  2. название альбома
  3. описание альбома
  4. автор альбома

об отдельной фотографии

  1. название
  2. автор
  3. описание
  4. теги-метки
  5. путь к оригиналу
  6. размер оригинала в байтах
  7. уровень доступа
  8. дата публикации

Работаем с альбомом

Тут все совсем просто

// ID альбома
var str = data.id;
    str = str.split(':');
alert(str[5]);
// название альбома
alert(data.title);
// описание альбома
alert(data.summary);
// автор альбома
alert(data.authors[0].name);

Работаем с фотографиями

В принципе, мы можем обратиться к любой фотографии (то есть массиву внутри объекта entries) по его индексу и получить интересующее нас свойство. Например так

data.entries[9].summary
data.entries[9].links.alternate
data.entries[9].img.L.href

Но мы воспользуемся $.each, так как это существенно упростить задачу и позволит использовать условия для выборки. Код перебора может так:

// функция-обработчик json-данных
function myFunc (data) {
    // строка-хранилище для искомых фото
    var need = 'Стесняется, \n\
                А это - подружка, \n\
                Ещё семья, я смущаюсь, Добры молодцы';    
    $.each(data.entries, function(key,val){ 
        // условие
        // если val.summary есть в хранилище
        if (need.indexOf(val.summary) !== -1) {
            $('#qwe').append('Значение ключа '+key+' : '+val+"<hr>");
            // то мы перебираем этот объект
            // название
            alert(val.title);
            // автор
            alert(val.authors[0].name);
            // описание
            alert(val.summary);
            // теги-метки
            var tags = '';
            $.each(val.tags, function(ke,va){
                tags += ke+',';
            }); 
            tags = tags.slice(0,-1);
            alert(tags);
            // путь к оригиналу
            alert(val.img.orig.href);
            // размер оригинала в байтах
            alert(val.img.orig.bytesize);
            // уровень доступа
            alert(val.access);
            // дата публикации
            alert(val.published);
        }
    });
}

Вот, пожалуй, и все.


Ссылки по теме статьи: