Analysieren der JSONP $ http.jsonp () -Antwort in angle.js

112

Ich verwende die $http.jsonp()Anfrage von angle, die erfolgreich json zurückgibt, das in eine Funktion eingeschlossen ist:

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=jsonp_callback";

$http.jsonp(url).
    success(function(data, status, headers, config) {
        //what do I do here?
    }).
    error(function(data, status, headers, config) {
        $scope.error = true;
    });

Wie kann ich auf den zurückgegebenen Function-Wrapped-JSON zugreifen / ihn analysieren?

akronymn
quelle
4
Mit JSONP können Sie nicht "auf das zurückgegebene funktionsumhüllte JSON zugreifen / es analysieren". Ihr Rückruf wird aufgerufen; Es empfängt die JSON-Daten als Argument.
Matt Ball
Ich habe versucht, so etwas wie
akronymn
(Entschuldigung, drücken Sie oben zu früh die Eingabetaste.) Ab wann wird mein Rückruf aufgerufen? Ein Code-Snippet wäre wirklich hilfreich. Ich habe zu diesem Zeitpunkt verschiedene Dinge ausprobiert und bin ratlos.
Akronymn
Der Rückruf wird aufgerufen, wenn die Antwort zurückkommt. Haben Sie eine Funktion namens jsonp_callback? Wenn nicht, gibt es Ihr Problem.
Matt Ball
im Moment habe ich eine einfache Funktion geschrieben, um nur das erste Element des json zurückzugeben, function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

Antworten:

300

UPDATE: seit Angular 1.6

Sie können die Zeichenfolge JSON_CALLBACK nicht mehr als Platzhalter verwenden, um anzugeben, wohin der Wert des Rückrufparameters gehen soll

Sie müssen den Rückruf nun wie folgt definieren:

$http.jsonp('some/trusted/url', {jsonpCallbackParam: 'callback'})

Parameter ändern / zugreifen / deklarieren über $http.defaults.jsonpCallbackParam, standardmäßigcallback

Hinweis: Sie müssen auch sicherstellen, dass Ihre URL zur vertrauenswürdigen / Whitelist hinzugefügt wird:

$sceDelegateProvider.resourceUrlWhitelist

oder explizit vertrauenswürdig über:

$sce.trustAsResourceUrl(url)

success/errorwurden veraltet .

Das $http Legacy - Versprechen Methoden successund sind errorveraltet und wird in v1.6.0 entfernt werden. Verwenden Sie stattdessen die Standard-Then-Methode. Wenn auf $httpProvider.useLegacyPromiseExtensionsgesetzt ist, werden falsediese Methoden ausgelöst $http/legacy error.

VERWENDEN:

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts"
var trustedUrl = $sce.trustAsResourceUrl(url);

$http.jsonp(trustedUrl, {jsonpCallbackParam: 'callback'})
    .then(function(data){
        console.log(data.found);
    });

Vorherige Antwort: Angular 1.5.x und früher

Alles was Sie tun müssen, ist sich zu ändern callback=jsonp_callback zu callback=JSON_CALLBACKetwa so:

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";

Und dann sollte Ihre .successFunktion so ausgelöst werden, wie Sie sie haben, wenn die Rückgabe erfolgreich war.

Wenn Sie dies auf diese Weise tun, müssen Sie den globalen Raum nicht verschmutzen. Dies ist in der AngularJS-Dokumentation dokumentiert hier .

Die Geige von Matt Ball wurde aktualisiert, um diese Methode zu verwenden: http://jsfiddle.net/subhaze/a4Rc2/114/

Vollständiges Beispiel:

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";

$http.jsonp(url)
    .success(function(data){
        console.log(data.found);
    });
subhaze
quelle
5
meins gibt einen anderen Rückruf zurück: angular.callbacks._0 Wie soll ich das beheben?
Raberana
@ eaon21 hast du ein Geigenbeispiel?
Subhaze
2
@ eaon21 es ist das gewünschte Verhalten, Winkel ersetzt JSON_CALLBACK durch ein dynamisch generiertes, Sie müssen nicht darauf achten
Guillaume86
Und wie nennt man zum Beispiel Youtube API?
Gino
Es scheint, dass sie eine eigene clientseitige Bibliothek für die Interaktion mit der API haben. Gibt es Beispiele, mit denen Sie eingrenzen können, was Sie tun möchten?
Subhaze
69

Das WICHTIGSTE, was ich eine ganze Weile nicht verstanden habe, ist, dass die Anfrage "callback = JSON_CALLBACK" enthalten MUSS , da AngularJS die Anforderungs-URL ändert und "JSON_CALLBACK" durch eine eindeutige Kennung ersetzt. Die Serverantwort muss den Wert des Parameters 'callback' verwenden, anstatt "JSON_CALLBACK" fest zu codieren:

JSON_CALLBACK(json_response);  // wrong!

Da ich mein eigenes PHP-Serverskript schrieb, dachte ich, ich wüsste, welchen Funktionsnamen es wollte, und musste in der Anfrage nicht "callback = JSON_CALLBACK" übergeben. Großer Fehler!

AngularJS ersetzt "JSON_CALLBACK" in der Anforderung durch einen eindeutigen Funktionsnamen (wie "callback = angular.callbacks._0"), und die Serverantwort muss diesen Wert zurückgeben:

angular.callbacks._0(json_response);
Joseph Oster
quelle
2
Gibt es eine Möglichkeit, den Namen des Rückrufs so zu ändern, dass er mit einer fest codierten statischen jsonDatei funktioniert?
Pavel Nikolov
9

Das war sehr hilfreich. Angular funktioniert nicht genau wie JQuery. Es verfügt über eine eigene jsonp () -Methode, für die am Ende der Abfragezeichenfolge tatsächlich "& callback = JSON_CALLBACK" erforderlich ist. Hier ist ein Beispiel:

var librivoxSearch = angular.module('librivoxSearch', []);
librivoxSearch.controller('librivoxSearchController', function ($scope, $http) {
    $http.jsonp('http://librivox.org/api/feed/audiobooks/author/Melville?format=jsonp&callback=JSON_CALLBACK').success(function (data) {
        $scope.data = data;
    });
});

Zeigen Sie dann {{data}} in Ihrer Angular-Vorlage an oder bearbeiten Sie sie.

Peter
quelle
4

Dies sollte für Sie in Ordnung sein, solange die Funktion jsonp_callbackim globalen Bereich sichtbar ist:

function jsonp_callback(data) {
    // returning from async callbacks is (generally) meaningless
    console.log(data.found);
}

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=jsonp_callback";

$http.jsonp(url);

Vollständige Demo: http://jsfiddle.net/mattball/a4Rc2/ (Haftungsausschluss: Ich habe noch nie einen AngularJS-Code geschrieben)

Matt Ball
quelle
Das hat es geschafft! Es stellt sich heraus, dass ich es vermasselt habe. Danke dir!
Akronymn
1
Diese Antwort war nicht sehr hilfreich. Es folgt nicht dem Umfang von AngularJS.
xil3
1
@ xil3 danke für das Feedback; Leider kann nur das OP (akronymn) die akzeptierte Antwort wechseln, nicht ich.
Matt Ball
@DanieleBrugnara Bitte beachten Sie die vorherigen Kommentare zu dieser Antwort.
Matt Ball
4

Sie müssen noch callbackdie Parameter einstellen:

var params = {
  'a': b,
  'token_auth': TOKEN,
  'callback': 'functionName'
};
$sce.trustAsResourceUrl(url);

$http.jsonp(url, {
  params: params
});

Dabei ist 'functionName' ein String-Verweis auf eine global definierte Funktion. Sie können es außerhalb Ihres Winkelskripts definieren und dann in Ihrem Modul neu definieren.

Paradit
quelle
2

Zum Parsen tun Sie dies-

   $http.jsonp(url).
    success(function(data, status, headers, config) {
    //what do I do here?
     $scope.data=data;
}).

Oder Sie können `$ scope.data = JSON.Stringify (data) verwenden;

In der Angular-Vorlage können Sie sie als verwenden

{{data}}
kapil
quelle
0

Für mich funktionierten die oben genannten Lösungen nur, wenn ich den Anforderungsparametern "format = jsonp" hinzufügte.

Tali
quelle
0

Ich verwende Angular 1.6.4 und die Antwort von Subhaze hat bei mir nicht funktioniert. Ich habe es ein wenig modifiziert und dann hat es funktioniert - Sie müssen den von $ sce.trustAsResourceUrl zurückgegebenen Wert verwenden . Vollständiger Code:

var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts"
url = $sce.trustAsResourceUrl(url);

$http.jsonp(url, {jsonpCallbackParam: 'callback'})
    .then(function(data){
        console.log(data.found);
    });
Mikatuo
quelle