Базовый пример использования .ajax () с JSONP?

180

Пожалуйста, помогите мне разобраться, как начать работу с JSONP?

код:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    var photos = function (data) {
     alert(data);
    };
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: false,
    });
});

Fiddle: http://jsfiddle.net/R7EPt/6/

Должен выдавать предупреждение, насколько я могу это сделать из документации: нет (но и не вызывает никаких ошибок).

спасибо.

  • 0
    $ .ajax ({url: pm_url, dataType: 'jsonp', jsonpCallback: photos, jsonp: false,}); Вы ввели фотографии в виде строки.
Теги:
jsonp

4 ответа

367

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. (очень плохо названная техника, так как она действительно не имеет ничего общего с тем, что большинство людей будет воспринимать как "заполнение".)

  • 3
    Этот ответ теперь несколько устарел, потому что браузеры теперь поддерживают заголовки Access-Control-Allow-Origin которые позволяют совершать регулярные вызовы Ajax в некоторые домены разных источников.
  • 0
    Имейте в виду, что вы не можете сделать форму POST с JSONP. Более подробная информация здесь: markhneedham.com/blog/2009/08/27/…
Показать ещё 3 комментария
132

Существует еще более простой способ работы с JSONP с помощью jQuery

$.getJSON("http://example.com/something.json?callback=?", function(result){
   //response data are now in the result variable
   alert(result);
});

? в конце URL-адреса сообщает jQuery, что это JSONP-запрос вместо JSON. jQuery регистрирует и вызывает функцию обратного вызова автоматически.

Подробнее см. В документации jQuery.getJSON.

  • 2
    Это действительно хороший трюк jQuery, спасибо.
  • 0
    Великий приятель! Почему эти ответы не отмечены как полезные?
Показать ещё 12 комментариев
24

В ответ на OP есть две проблемы с вашим кодом: вам нужно установить jsonp = 'callback', а добавление функции обратного вызова в переменной, как вы, похоже, не работает.

Обновление: когда я написал это, API Twitter был только открыт, но они изменили его, и теперь он требует аутентификации. Я изменил второй пример на рабочий (2014Q1) пример, но теперь с помощью github.

Это больше не работает - как упражнение, посмотрите, можете ли вы заменить его API Github:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: 'callback',
    });
});
function photos (data) {
    alert(data);
    console.log(data);
};

хотя alert() для такого массива не очень хорошо работает... Вкладка "Net" в Firebug покажет вам JSON правильно. Другой удобный трюк делает

alert(JSON.stringify(data));

Вы также можете использовать метод jQuery.getJSON. Вот полный пример html, который получает список "gists" из github. Таким образом, для вас создается случайная функция обратного вызова, что конечный "callback =?" в URL.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>JQuery (cross-domain) JSONP Twitter example</title>
        <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.getJSON('https://api.github.com/gists?callback=?', function(response){
                    $.each(response.data, function(i, gist){
                        $('#gists').append('<li>' + gist.user.login + " (<a href='" + gist.html_url + "'>" + 
                            (gist.description == "" ? "undescribed" : gist.description) + '</a>)</li>');
                    });
                });
            });
        </script>
    </head>
    <body>
        <ul id="gists"></ul>
    </body>
</html>
  • 0
    нет это не работает
  • 2
    Ты прав, это больше не работает. Твиттер изменил свой API.
3
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<title>An JSONP example </title>
</head>
<body>
<!-- DIV FOR SHOWING IMAGES -->
<div id="images">
</div>
<!-- SCRIPT FOR GETTING IMAGES FROM FLICKER.COM USING JSONP -->
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
  format: "json"
},
//RETURNED RESPONSE DATA IS LOOPED AND ONLY IMAGE IS APPENDED TO IMAGE DIV
function(data) {
  $.each(data.items, function(i,item){
  $("<img/>").attr("src", item.media.m).appendTo("#images");

 });
});</script>
</body>
</html> 

Приведенный выше код помогает получить изображения из API Flicker. Это использует метод GET для получения изображений с использованием JSONP. Это можно найти в здесь

Ещё вопросы

Сообщество Overcoder
Наверх
Меню