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?


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);
    });

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);

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.


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)


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.


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}}

0

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


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);
    });
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.