mengurai respons JSONP $ http.jsonp () di angular.js

112

Saya menggunakan $http.jsonp()permintaan angular yang berhasil mengembalikan json yang dibungkus dalam sebuah fungsi:

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

Bagaimana cara mengakses / mengurai fungsi-dibungkus-JSON yang dikembalikan?

akronim
sumber
4
Dengan JSONP Anda tidak "mengakses / mengurai JSON yang dibungkus fungsi yang dikembalikan". Panggilan balik Anda dipanggil; itu menerima data JSON sebagai argumen.
Matt Ball
Saya sudah mencoba melakukan sesuatu seperti
akronim
(maaf tekan enter terlalu cepat di atas) Kapan panggilan balik saya dipanggil? Cuplikan kode akan sangat membantu. Saya telah mencoba sejumlah hal berbeda pada saat ini dan saya bingung.
akronim
Callback dipanggil saat respons kembali. Apakah Anda memiliki fungsi bernama jsonp_callback? Jika tidak, itu masalah Anda.
Matt Ball
untuk saat ini saya telah menulis fungsi sederhana untuk mengembalikan elemen pertama dari json, function jsonp_callback(data) { return data.found; //should be 3 }
akronim

Jawaban:

300

PEMBARUAN: sejak Angular 1.6

Anda tidak dapat lagi menggunakan string JSON_CALLBACK sebagai placeholder untuk menentukan ke mana nilai parameter callback harus pergi

Anda sekarang harus menentukan callback seperti ini:

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

Ubah / akses / deklarasikan param via $http.defaults.jsonpCallbackParam, default kecallback

Catatan: Anda juga harus memastikan URL Anda ditambahkan ke Trusted / Whitelist:

$sceDelegateProvider.resourceUrlWhitelist

atau dipercaya secara eksplisit melalui:

$sce.trustAsResourceUrl(url)

success/errortidak digunakan lagi .

Metode $httpjanji lama successdan errorsudah tidak digunakan lagi dan akan dihapus di v1.6.0. Gunakan metode standar lalu sebagai gantinya. Jika $httpProvider.useLegacyPromiseExtensionsdiatur ke falsemaka metode ini akan melempar $http/legacy error.

MENGGUNAKAN:

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

Jawaban Sebelumnya: Angular 1.5.x dan sebelumnya

Yang harus Anda lakukan adalah berubah callback=jsonp_callbackmenjadi callback=JSON_CALLBACKseperti ini:

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

Dan kemudian .successfungsi Anda harus aktif seperti yang Anda miliki jika pengembalian berhasil.

Melakukannya dengan cara ini membuat Anda tidak perlu mengotori ruang global. Ini didokumentasikan dalam dokumentasi AngularJS di sini .

Memperbarui biola Matt Ball untuk menggunakan metode ini: http://jsfiddle.net/subhaze/a4Rc2/114/

Contoh lengkap:

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
sumber
5
milik saya mengembalikan panggilan balik yang berbeda: angular.callbacks._0 bagaimana cara memperbaikinya?
raberana
@ eaon21 apakah Anda memiliki contoh biola?
subhaze
2
@ eaon21 ini adalah perilaku yang diinginkan, pengganti sudut JSON_CALLBACK menjadi yang dibuat secara dinamis, Anda tidak perlu memperhatikannya
Guillaume86
Dan bagaimana Anda menyebut api Youtube misalnya?
Gino
Tampaknya mereka memiliki lib sisi klien sendiri untuk berinteraksi dengan API. Adakah contoh yang Anda miliki yang dapat membantu mempersempit apa yang Anda coba lakukan?
subhaze
69

The HAL PENTING YANG PALING saya tidak mengerti cukup sebentar adalah bahwa permintaan HARUS mengandung "callback = JSON_CALLBACK", karena AngularJS memodifikasi permintaan url , menggantikan pengenal unik untuk "JSON_CALLBACK". Respons server harus menggunakan nilai parameter 'callback' sebagai ganti hard coding "JSON_CALLBACK":

JSON_CALLBACK(json_response);  // wrong!

Karena saya menulis skrip server PHP saya sendiri, saya pikir saya tahu nama fungsi apa yang diinginkannya dan tidak perlu meneruskan "callback = JSON_CALLBACK" dalam permintaan. Kesalahan besar!

AngularJS menggantikan "JSON_CALLBACK" dalam permintaan dengan nama fungsi unik (seperti "callback = angular.callbacks._0"), dan respons server harus mengembalikan nilai itu:

angular.callbacks._0(json_response);
Joseph Oster
sumber
2
Adakah cara kita dapat mengubah nama callback agar berfungsi dengan jsonfile statis berkode keras .
Pavel Nikolov
9

Ini sangat membantu. Angular tidak berfungsi persis seperti JQuery. Ia memiliki metode jsonp () sendiri, yang memang membutuhkan "& callback = JSON_CALLBACK" di akhir string kueri. Berikut contohnya:

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

Kemudian tampilkan atau manipulasi {{data}} di template Angular Anda.

Peter
sumber
4

Ini seharusnya berfungsi dengan baik untuk Anda, selama fungsinya jsonp_callbackterlihat dalam cakupan global:

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

Demo lengkap: http://jsfiddle.net/mattball/a4Rc2/ (penafian: Saya belum pernah menulis kode AngularJS sebelumnya)

Matt Ball
sumber
Berhasil! Ternyata ruang lingkup yang saya buat kacau. Terima kasih!
akronim
1
Jawaban ini tidak terlalu membantu. Itu tidak mengikuti lingkup AngularJS.
xil3
1
@ xil3 terima kasih atas umpan baliknya; sayangnya hanya OP (akronim) yang dapat mengganti jawaban yang diterima, bukan saya.
Matt Ball
@DanieleBrugnara silakan lihat komentar sebelumnya untuk jawaban ini.
Matt Ball
4

Anda masih perlu mengatur callbackdi params:

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

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

Di mana 'functionName' adalah referensi yang dirangkai ke fungsi yang ditentukan secara global. Anda dapat menentukannya di luar skrip sudut Anda dan kemudian mendefinisikannya kembali dalam modul Anda.

paradit
sumber
2

Untuk parsing lakukan ini-

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

Atau Anda dapat menggunakan `$ scope.data = JSON.Stringify (data);

Dalam template Angular Anda dapat menggunakannya sebagai

{{data}}
kapil
sumber
0

bagi saya solusi di atas hanya bekerja setelah saya menambahkan "format = jsonp" ke parameter permintaan.

Tali
sumber
0

Saya menggunakan sudut 1.6.4 dan jawaban yang diberikan oleh subhaze tidak berhasil untuk saya. Saya memodifikasinya sedikit dan kemudian berhasil - Anda harus menggunakan nilai yang dikembalikan oleh $ sce.trustAsResourceUrl . Kode lengkap:

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
sumber