Ответ 1
JSONP - действительно простой трюк для преодоления той же политики домена XMLHttpRequest. (Как вы знаете, нельзя отправить запрос AJAX (XMLHttpRequest) в другой домен.)
Итак, вместо XMLHttpRequest мы должны использовать теги script HTMLl, те, которые вы обычно используете для загрузки JS файлов, чтобы JS мог получать данные из другого домена. Звучит странно?
Вещь - получается script теги могут использоваться по типу, подобному XMLHttpRequest! Проверьте это:
script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data";
В итоге вы получите сегмент script, который выглядит следующим образом после загрузки данных:
<script>
{['some string 1', 'some data', 'whatever data']}
</script>
Однако это немного неудобно, потому что мы должны получить этот массив из тега script. Поэтому создатели JSONP решили, что это будет работать лучше (и это так):
script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data?callback=my_callback";
Обратите внимание на функцию my_callback? Итак - когда сервер JSONP получает ваш запрос и находит параметр обратного вызова - вместо того, чтобы возвращать простой массив JS, он вернет это:
my_callback({['some string 1', 'some data', 'whatever data']});
Посмотрите, где прибыль: теперь мы получаем автоматический обратный вызов (my_callback), который будет запущен после получения данных. Это все, что нужно знать о JSONP: это обратный вызов и теги script.
Примечание:
Это простые примеры использования JSONP, это не готовые сценарии производства.
демонстрация RAW JavaScript (простая лента Twitter с использованием JSONP):
<html>
<head>
</head>
<body>
<div id = 'twitterFeed'></div>
<script>
function myCallback(dataWeGotViaJsonp){
var text = '';
var len = dataWeGotViaJsonp.length;
for(var i=0;i<len;i++){
twitterEntry = dataWeGotViaJsonp[i];
text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
}
document.getElementById('twitterFeed').innerHTML = text;
}
</script>
<script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
</body>
</html>
Основной пример jQuery (простой канал Twitter с использованием JSONP):
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.ajax({
url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
dataType: 'jsonp',
success: function(dataWeGotViaJsonp){
var text = '';
var len = dataWeGotViaJsonp.length;
for(var i=0;i<len;i++){
twitterEntry = dataWeGotViaJsonp[i];
text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
}
$('#twitterFeed').html(text);
}
});
})
</script>
</head>
<body>
<div id = 'twitterFeed'></div>
</body>
</html>
JSONP означает JSON с Padding. (очень плохо названная техника, так как она действительно не имеет ничего общего с тем, что большинство людей будет воспринимать как "заполнение".)