Grundlegendes Beispiel für die Verwendung von .ajax () mit JSONP?

185

Könnte mir bitte jemand helfen, herauszufinden, wie ich mit JSONP anfangen kann?

Code:

$('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,
    });
});

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

Sollte eine Warnung erzeugen, soweit ich aus der Dokumentation ersehen kann: ist nicht (erzeugt aber auch keine Fehler).

Vielen Dank.

Simon
quelle
$ .ajax ({url: pm_url, Datentyp: 'jsonp', jsonpCallback: photos, jsonp: false,}); Sie haben Fotos als Zeichenfolge eingegeben.
WOlVeRiNe

Antworten:

388

JSONP ist wirklich ein einfacher Trick, um dieselbe Domain-Richtlinie von XMLHttpRequest zu überwinden . (Wie Sie wissen, kann eine AJAX- Anfrage (XMLHttpRequest) nicht an eine andere Domain gesendet werden.)

Anstatt XMLHttpRequest zu verwenden, müssen wir Skript- HTMLl-Tags verwenden, die Sie normalerweise zum Laden von JS-Dateien verwenden, damit JS Daten von einer anderen Domäne abruft. Klingt komisch?

Es stellt sich heraus, dass Skript- Tags ähnlich wie XMLHttpRequest verwendet werden können ! Überprüfen Sie dies heraus:

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

Sie erhalten ein Skriptsegment , das nach dem Laden der Daten folgendermaßen aussieht:

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

Dies ist jedoch etwas unpraktisch, da wir dieses Array vom Skript- Tag abrufen müssen. Daher haben JSONP- Entwickler entschieden, dass dies besser funktioniert (und das ist es auch):

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

Beachten Sie die Funktion my_callback dort drüben? Wenn der JSONP- Server Ihre Anfrage empfängt und den Rückrufparameter findet, wird anstelle eines einfachen JS-Arrays Folgendes zurückgegeben:

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

Sehen Sie, wo der Gewinn liegt: Jetzt erhalten wir einen automatischen Rückruf ( my_callback ), der ausgelöst wird, sobald wir die Daten erhalten. Das ist alles, was Sie über JSONP wissen müssen : Es handelt sich um einen Rückruf und Skript-Tags.


ANMERKUNG:
Dies sind einfache Beispiele für die Verwendung von JSONP. Dies sind keine produktionsfertigen Skripte.

RAW-JavaScript-Demonstration (einfacher Twitter-Feed mit 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>


Grundlegendes jQuery-Beispiel (einfacher Twitter-Feed mit 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 steht für JSON with Padding . (Sehr schlecht benannte Technik, da sie wirklich nichts mit dem zu tun hat, was die meisten Leute als „Polsterung“ betrachten würden.)

Dieser Typ
quelle
3
Diese Antwort ist jetzt etwas veraltet, da Browser jetzt Access-Control-Allow-OriginHeader unterstützen, mit denen regelmäßige Ajax-Aufrufe an einige Ursprungsdomänen getätigt werden können.
jfriend00
Beachten Sie, dass Sie mit JSONP kein Formular POST erstellen können. Weitere Infos hier: markhneedham.com/blog/2009/08/27/…
thdoan
4
Was müssen Sie beachten, wenn Sie diese Skripte produktionsbereit machen möchten?
Gast
1
Wow, das ist wirklich hilfreich! Endlich erfahre ich, was genau JSONP ist und wie es funktioniert!
Jerry Liu
145

Es gibt noch einfachere Möglichkeiten, mit JSONP mithilfe von jQuery zu arbeiten

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

Das ? am Ende der URL teilt jQuery mit, dass es sich um eine JSONP-Anforderung anstelle von JSON handelt. jQuery registriert und ruft die Rückruffunktion automatisch auf.

Weitere Informationen finden Sie in der Dokumentation zu jQuery.getJSON .

Petr Peller
quelle
2
@PetrPeller, Scheint großartig, aber ich scheine kein Produkt daraus zu machen. Kannst du das mal sehen? JSFiddle Es werden keine Daten benachrichtigt . Vielleicht habe ich etwas verpasst
Tika
Die JSONP-Antwort @xDNP muss vom Server unterstützt werden. Ihr Server scheint dies nicht zu unterstützen, da ich hier keinen zusätzlichen Rückruf sehen kann: mylivecanvas.com/api/… . Sie sollten auch verwenden, &callback=?da dies in Ihrem Fall nicht der erste Parameter ist.
Petr Peller
1
@PetrPeller Ich bin sehr an Ihrer Lösung interessiert. Aber das funktioniert bei mir nicht. Ich möchte keine neue Frage stellen, aber es hilft mir nicht. Was scheint Server nicht zu unterstützen ? Was soll ich machen? Und können Sie mir eine vollständige URL geben, die für meinen Server funktioniert? Ich wäre dir dankbar. Benötige ich eine Serverkonfiguration?
Tika
3
Was bewirkt die letzte Bearbeitung: "Bitte benutze jQuery nicht mehr!" bedeuten?
ParkCheolu
1
Es ist jetzt 2018 und ich bin mir nicht sicher, was 2017 überhaupt verwendet werden soll!
Vasily Hall
28

Als Reaktion auf das OP gibt es zwei Probleme mit Ihrem Code: Sie müssen jsonp = 'callback' setzen, und das Hinzufügen einer Rückruffunktion in einer Variablen, wie Sie es getan haben, scheint nicht zu funktionieren.

Update: Als ich dies schrieb, war die Twitter-API gerade geöffnet, aber sie wurde geändert und erfordert jetzt eine Authentifizierung. Ich habe das zweite Beispiel in ein funktionierendes Beispiel (2014Q1) geändert, verwende aber jetzt Github.

Dies funktioniert nicht mehr - prüfen Sie als Übung, ob Sie es durch die Github-API ersetzen können:

$('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);
};

Obwohl alert () für ein solches Array nicht wirklich gut funktioniert ... Auf der Registerkarte "Net" in Firebug wird der JSON korrekt angezeigt. Ein weiterer praktischer Trick ist zu tun

alert(JSON.stringify(data));

Sie können auch die Methode jQuery.getJSON verwenden. Hier ist ein vollständiges HTML-Beispiel, das eine Liste der "Gists" von Github erhält. Auf diese Weise wird eine zufällig benannte Rückruffunktion für Sie erstellt, das ist der endgültige "Rückruf =?" in der 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
quelle
2
Du hast recht, es funktioniert nicht mehr. Twitter hat seine API geändert.
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> 

Der obige Code hilft beim Abrufen von Bildern von der Flicker-API. Dies verwendet die GET-Methode zum Abrufen von Bildern mit JSONP. Es kann hier im Detail gefunden werden

Ganesh Babu
quelle