Сила 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