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="http://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:
- Yahoo – поиск и большинство сервисов
- Flickr – работа с поиском данного сервиса
- MediaWiki – соответственно и производные – Wikipedia, Wiktionary
- CNET – поиск по новостному порталу
Для иллюстрации работы попробуем на зуб 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.