Podstawowy przykład użycia .ajax () z JSONP?

187

Czy ktoś mógłby mi pomóc w ustaleniu, jak zacząć korzystać z JSONP?

Kod:

$('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/

Powinien wygenerować alert, o ile mogę wypracować na podstawie dokumentacji: nie jest (ale też nie powoduje żadnych błędów).

dzięki.

Szymon
źródło
$ .ajax ({url: pm_url, dataType: 'jsonp', jsonpCallback: zdjęcia, jsonp: false,}); Wpisałeś zdjęcia jako ciąg.
WOlVeRiNe

Odpowiedzi:

388

JSONP to naprawdę prosta sztuczka, aby pokonać XMLHttpRequest w tej samej polityce domenowej. (Jak wiadomo, nie można wysłać żądania AJAX (XMLHttpRequest) do innej domeny).

Tak więc - zamiast używać XMLHttpRequest, musimy użyć skryptowych znaczników HTMLl, tych, których zwykle używasz do ładowania plików JS, aby JS mógł uzyskać dane z innej domeny. Brzmi dziwnie?

Chodzi o to - okazuje się, że tagi skryptu mogą być używane w sposób podobny do XMLHttpRequest ! Sprawdź to:

script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data";

Otrzymasz segment skryptu, który wygląda tak po załadowaniu danych:

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

Jest to jednak nieco niewygodne, ponieważ musimy pobrać tę tablicę ze znacznika script . Dlatego twórcy JSONP zdecydowali, że będzie to działać lepiej (i tak jest):

script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data?callback=my_callback";

Czy zauważyłeś tam funkcję my_callback ? Tak więc - gdy serwer JSONP otrzyma twoje żądanie i znajdzie parametr wywołania zwrotnego - zamiast zwracać zwykłą tablicę JS zwróci to:

my_callback({['some string 1', 'some data', 'whatever data']});

Zobacz, gdzie jest zysk: teraz otrzymujemy automatyczne oddzwanianie ( my_callback ), które zostanie uruchomione, gdy otrzymamy dane. To wszystko, co należy wiedzieć o JSONP : jest to callback i tagi skryptowe.


UWAGA:
Są to proste przykłady użycia JSONP, nie są to skrypty gotowe do produkcji.

Demonstracja RAW JavaScript (prosty kanał Twittera przy użyciu 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>


Podstawowy przykład jQuery (prosty kanał Twittera przy użyciu 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 oznacza JSON z Padding . (bardzo źle nazwana technika, ponieważ tak naprawdę nie ma nic wspólnego z tym, co większość ludzi uważałaby za „padding”).

Ten facet
źródło
3
Ta odpowiedź jest obecnie nieco nieaktualna, ponieważ przeglądarki obsługują teraz Access-Control-Allow-Originnagłówki, które umożliwiają wykonywanie regularnych wywołań Ajax w niektórych domenach pochodzących z różnych źródeł.
jfriend00
Pamiętaj, że nie możesz zrobić formularza POST z JSONP. Więcej informacji tutaj: markhneedham.com/blog/2009/08/27/...
thdoan
4
Co musisz wziąć pod uwagę, jeśli chcesz przygotować te skrypty do produkcji?
gość
1
Wow, to jest naprawdę pomocne! W końcu dowiaduję się, czym dokładnie jest JSONP i jak to działa!
Jerry Liu,
146

Jest jeszcze łatwiejszy sposób pracy z JSONP za pomocą jQuery

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

?Na końcu adresu URL jQuery mówi, że jest to JSONP prośba zamiast JSON. jQuery automatycznie rejestruje i wywołuje funkcję zwrotną.

Aby uzyskać więcej informacji, zapoznaj się z dokumentacją jQuery.getJSON .

Petr Peller
źródło
2
@PetrPeller, Wydaje się, że świetnie, ale nie wydaje mi się, żebym tworzył z niego produkt. Czy raz to widzisz? JSFiddle Alarmuje brak danych. Może coś mi umknęło
tika
@xDNP Odpowiedź JSONP musi być obsługiwana przez serwer. Twój serwer zdaje się go nie obsługiwać, ponieważ nie widzę tutaj żadnego dodatkowego wywołania zwrotnego: mylivecanvas.com/api/… . Powinieneś również użyć, &callback=?ponieważ nie jest to pierwszy parametr w twoim przypadku.
Petr Peller
1
@PetrPeller Jestem bardzo zainteresowany twoim rozwiązaniem. Ale to nie działa na mnie. Nie chcę publikować nowego pytania, ale to mi nie pomaga. Co wydaje się nie być obsługiwane przez serwer ? Co powinienem zrobić? Czy możesz podać mi pełny adres URL, który działa na moim serwerze? Byłbym ci wdzięczny. Czy potrzebuję konfiguracji serwera?
tika
3
Co robi ostatnia edycja: „Proszę nie używać jQuery!” oznaczać?
ParkCheolu,
1
Jest rok 2018 i nie jestem pewien, co powinno być wykorzystane w 2017 roku!
Vasily Hall
28

W odpowiedzi na OP występują dwa problemy z twoim kodem: musisz ustawić jsonp = 'callback', a dodanie funkcji callback w zmiennej takiej jak ty nie wydaje się działać.

Aktualizacja: kiedy to napisałem, interfejs API Twittera był po prostu otwarty, ale zmienili go i teraz wymaga uwierzytelnienia. Zmieniłem drugi przykład na działający (2014Q1), ale teraz korzystam z github.

To już nie działa - w ramach ćwiczenia sprawdź, czy możesz go zastąpić interfejsem 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);
};

chociaż alert () takiej tablicy nie działa tak naprawdę ... Zakładka „Net” we Firebug odpowiednio wyświetli JSON. Kolejna przydatna sztuczka

alert(JSON.stringify(data));

Możesz także użyć metody jQuery.getJSON . Oto kompletny przykład HTML, który pobiera listę „gists” z github. W ten sposób tworzy dla ciebie losowo nazwaną funkcję oddzwaniania, jest to końcowa „callback =?” w adresie 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>
PapaFreud
źródło
2
Masz rację, to już nie działa. Twitter zmienił ich interfejs API.
PapaFreud
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> 

Powyższy kod pomaga w uzyskiwaniu obrazów z interfejsu API Flicker. Wykorzystuje metodę GET do pobierania obrazów przy użyciu JSONP. Można go szczegółowo znaleźć tutaj

Ganesh Babu
źródło