parsowanie odpowiedzi JSONP $ http.jsonp () w angular.js

112

Używam $http.jsonp()żądania angulara, które pomyślnie zwraca json opakowane w funkcję:

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

Jak uzyskać dostęp / przeanalizować zwróconą funkcję-zawiniętą-JSON?

akronymn
źródło
4
Dzięki JSONP nie „uzyskujesz dostępu / analizujesz zwróconej funkcji w formacie JSON”. Twoje oddzwonienie zostanie wywołane; otrzymuje dane JSON jako argument.
Matt Ball,
Próbowałem zrobić coś takiego
akronymn
(przepraszam, wciśnij Enter zbyt wcześnie powyżej) W którym momencie moje wywołanie zwrotne? Fragment kodu byłby naprawdę pomocny. W tym momencie wypróbowałem wiele różnych rzeczy i jestem zaskoczony.
akronymn
Wywołanie zwrotne jest wywoływane, gdy odpowiedź nadejdzie. Czy masz funkcję o nazwie jsonp_callback? Jeśli nie, to jest twój problem.
Matt Ball
na razie napisałem prostą funkcję, która po prostu zwraca pierwszy element json, function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

Odpowiedzi:

300

AKTUALIZACJA: od Angular 1.6

Nie możesz już używać ciągu JSON_CALLBACK jako symbolu zastępczego do określania, gdzie powinna znajdować się wartość parametru wywołania zwrotnego

Musisz teraz zdefiniować callback w następujący sposób:

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

Zmień / uzyskaj / zadeklaruj parametr przez $http.defaults.jsonpCallbackParam, domyślniecallback

Uwaga: musisz również upewnić się, że Twój adres URL został dodany do zaufanej / białej listy:

$sceDelegateProvider.resourceUrlWhitelist

lub jawnie zaufane przez:

$sce.trustAsResourceUrl(url)

success/errorzostały wycofane .

Te $httpmetody obietnica starszych successi errorbyły przestarzałe i zostaną usunięte w v1.6.0. Zamiast tego użyj metody standard then. Jeśli $httpProvider.useLegacyPromiseExtensionsjest ustawiona na, falsete metody będą generować $http/legacy error.

POSŁUGIWAĆ SIĘ:

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

Poprzednia odpowiedź: Angular 1.5.x i wcześniejsze

Wszystko, co powinieneś zrobić, to zmienić callback=jsonp_callbacksię callback=JSON_CALLBACKtak:

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

A potem twoja .successfunkcja powinna uruchomić się tak, jak ją masz, jeśli powrót się powiódł.

Robiąc to w ten sposób, nie musisz brudzić globalnej przestrzeni. Jest to udokumentowane w dokumentacji AngularJS tutaj .

Zaktualizowano skrzypce Matta Ball'a, aby używały tej metody: http://jsfiddle.net/subhaze/a4Rc2/114/

Pełny przykład:

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
źródło
5
mój zwraca inny callback: angular.callbacks._0 Jak mam to naprawić?
raberana
@ eaon21 czy masz przykład skrzypiec?
podhaze
2
@ eaon21 to pożądane zachowanie, angular zastępuje JSON_CALLBACK dynamicznie wygenerowanym, nie musisz na to zwracać uwagi
Guillaume86
A jak na przykład nazywasz interfejs API YouTube?
Gino
Wygląda na to, że mają własną bibliotekę po stronie klienta do interakcji z interfejsem API. Masz jakieś przykłady, które mogą pomóc zawęzić to, co próbujesz zrobić?
podhaze
69

Najważniejsze nie rozumiałem już od jakiegoś czasu jest to, że wniosek musi zawierać „callback = JSON_CALLBACK”, ponieważ angularjs modyfikuje URL żądania , zastępując unikalny identyfikator dla „JSON_CALLBACK”. Odpowiedź serwera musi zawierać wartość parametru „callback” zamiast „JSON_CALLBACK” na sztywno:

JSON_CALLBACK(json_response);  // wrong!

Ponieważ pisałem własny skrypt serwera PHP, pomyślałem, że wiem, jakiej nazwy funkcji potrzebuje i nie muszę podawać w żądaniu „callback = JSON_CALLBACK”. Wielkim błędem!

AngularJS zastępuje „JSON_CALLBACK” w żądaniu unikalną nazwą funkcji (np. „Callback = angular.callbacks._0”), a odpowiedź serwera musi zwrócić tę wartość:

angular.callbacks._0(json_response);
Joseph Oster
źródło
2
Czy istnieje sposób, w jaki możemy zmienić nazwę wywołania zwrotnego, aby działał z zakodowanym na stałe jsonplikiem statycznym?
Pavel Nikolov
9

To było bardzo pomocne. Angular nie działa dokładnie tak jak JQuery. Ma własną metodę jsonp (), która rzeczywiście wymaga „& callback = JSON_CALLBACK” na końcu ciągu zapytania. Oto przykład:

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

Następnie wyświetl lub manipuluj {{data}} w szablonie Angular.

Piotr
źródło
4

To powinno działać dobrze, o ile funkcja jsonp_callbackjest widoczna w zakresie globalnym:

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

Pełne demo: http://jsfiddle.net/mattball/a4Rc2/ (zastrzeżenie: nigdy wcześniej nie pisałem żadnego kodu AngularJS)

Matt Ball
źródło
Zrobiło to! Okazuje się, że zakres, który zawiodłem. Dziękuję Ci!
akronymn
1
Ta odpowiedź nie była zbyt pomocna. Nie jest zgodny z zakresem AngularJS.
xil3
1
@ xil3 dzięki za informację zwrotną; niestety tylko OP (akronymn) może zmienić zaakceptowaną odpowiedź, nie ja.
Matt Ball
@DanieleBrugnara, zobacz poprzednie komentarze do tej odpowiedzi.
Matt Ball
4

Nadal musisz ustawić callbackparametry:

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

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

Gdzie „nazwaFunkcji” to ujednolicone odniesienie do funkcji zdefiniowanej globalnie. Możesz zdefiniować go poza swoim skryptem kątowym, a następnie przedefiniować w swoim module.

paradyt
źródło
2

Do analizowania zrób to-

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

Lub możesz użyć `$ scope.data = JSON.Stringify (data);

W szablonie Angular możesz go używać jako

{{data}}
kapil
źródło
0

u mnie powyższe rozwiązania działały tylko wtedy, gdy dodałem "format = jsonp" do parametrów żądania.

Tali
źródło
0

Używam kątowego 1.6.4 i odpowiedź dostarczona przez subhaze nie działa dla mnie. Trochę go zmodyfikowałem i wtedy zadziałało - musisz użyć wartości zwracanej przez $ sce.trustAsResourceUrl . Pełny kod:

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
źródło