Сила JSONP

JSONP – это наш старый знакомый JSON с прослойкой в виде callback-функции О_о. Да ладно, давайте на примерах. Вот как у нас выглядит ответ сервера в формате JSON:

{
  "note": {
    "time":"2012.09.21 13:12:42",
    "text":"Рассказать, зачем нужен JSONP"
  }
}

Хорошо, когда у нас эти данные приходят с нашего сервера — обработаем, и всё будет чики-пики. Но если нам потребуется заполучить данные с другого сервера, то политика безопасности в браузерах не позволит отправить XMLHTTPRequest на другой сервер, и надо уже будет что-то придумывать. Можно чуть-чуть напрячься и вспомнить, что подключать JavaScript с другого сервера-то мы можем, и он будет выполнен. Вот она, зацепка, а если подключаемый скрипт будет содержать вызов нашей функции с подготовленными данными – то это уже что-то:

alertMe({
  "note":{
    "time":"2012.09.21 13:13:13",
    "text":"Каков же профит от использования JSONP?"
  }
})

Таким образом, описав в своём коде функцию alertMe(), мы сможем обработать данные с удалённого сервера. Зачастую сервера ловят параметр «callback» или «jsonp» и используют его как имя функции обёртки:

<script type="text/javascript" src="https://domain.com/getUsers/?callback=alertMe"></script>

Ну, это была предыстория, теперь вернёмся к jQuery и методу ajax():

$.ajax({
  url: "http://domain.com/getUsers/?callback=?", // указываем URL
  dataType: "jsonp",
  success: function (data) {
    // обрабатываем данные
  }
});

В запрашиваемом URL наблюдательный читатель заметит незаконченную структуру «callback=?». Так вот, вместо «?» будет подставлено имя новой сгенерированной функции, внутри которой будет осуществляться вызов функции success(). Вместо этой прокси-функции можно использовать и свою функцию, достаточно указать её имя в качестве параметра «jsonpCallback» при вызове $.ajax().

А ещё стоит упомянуть, что можно указать, как обзывается callback-параметр используя параметр jsonp. Таким образом, указав jsonp:"my" в URL, можно будет добавить структуру my=?.

На данный момент достаточно много сервисов предоставляют API с поддержкой JSONP:

  • Flickr — работа с поиском данного сервиса

  • MediaWiki — соответственно и производные – Wikipedia, Wiktionary

  • Tumblr — получение постов с сервиса

Для иллюстрации работы попробуем на зуб API от Flickr:

$.getJSON(
    "https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
    {
        tags: "orange",
        tagmode: "any",
        format: "json"
    },
    function(data) {
        $.each(data.items, function(i, item){
            $("<img/>")
                .attr("src", item.media.m)
                .appendTo("article");
        });
    }
);

Использование подобного подхода позволяет обходить ограничения, накладываемые сервисами на количество запросов с одного IP, плюс не грузит сервер дополнительной работой по проксированию запросов от пользователя к сервисам. Именно благодаря этому принципу у меня получилось создать сервис Analyser.

К сожалению, многие провайдеры сервисов (такие как Google) отказывают в предоставлении доступа к их API с использованием JSONP.

Last updated