phân tích cú pháp phản hồi JSONP $ http.jsonp () trong angle.js


112

Tôi đang sử dụng $http.jsonp()yêu cầu của angle đang trả về thành công json được bao bọc trong một hàm:

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

Làm cách nào để truy cập / phân tích cú pháp hàm được trả về JSON?


4
Với JSONP, bạn không "truy cập / phân tích cú pháp hàm được trả về-JSON được bao bọc." Cuộc gọi lại của bạn được gọi; nó nhận dữ liệu JSON như một đối số.
Matt Ball

Tôi đã thử làm điều gì đó giống như
akronymn

(xin lỗi, nhấn enter quá sớm ở trên) Cuộc gọi lại của tôi được gọi vào thời điểm nào? Một đoạn mã sẽ thực sự hữu ích. Tôi đã thử một số thứ khác nhau vào thời điểm này và rất bối rối.
akronymn

Cuộc gọi lại được gọi khi phản hồi quay trở lại. Bạn có một chức năng được đặt tên jsonp_callback? Nếu không, có vấn đề của bạn.
Matt Ball

bây giờ tôi đã viết một chức năng đơn giản để chỉ trả lại các yếu tố đầu tiên của json, function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

Câu trả lời:


300

CẬP NHẬT: kể từ Angular 1.6

Bạn không còn có thể sử dụng chuỗi JSON_CALLBACK làm trình giữ chỗ để chỉ định nơi giá trị tham số gọi lại sẽ đi

Bây giờ bạn phải xác định lệnh gọi lại như sau:

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

Thay đổi / truy cập / khai báo thông số qua $http.defaults.jsonpCallbackParam, mặc định làcallback

Lưu ý: Bạn cũng phải đảm bảo rằng URL của mình được thêm vào danh sách trắng / tin cậy:

$sceDelegateProvider.resourceUrlWhitelist

hoặc được tin cậy rõ ràng qua:

$sce.trustAsResourceUrl(url)

success/errorkhông được dùng nữa .

Các $httpphương thức hứa hẹn kế thừa successerrorđã không được dùng nữa và sẽ bị xóa trong v1.6.0. Sử dụng phương pháp then chuẩn thay thế. Nếu $httpProvider.useLegacyPromiseExtensionsđược đặt thành falsethì các phương thức này sẽ ném $http/legacy error.

SỬ DỤNG:

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

Câu trả lời trước: Angular 1.5.x và trước đó

Tất cả những gì bạn nên làm là thay đổi callback=jsonp_callbackthành callback=JSON_CALLBACKthích như vậy:

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

Và sau đó .successhàm của bạn sẽ kích hoạt như bạn có nếu trả về thành công.

Làm theo cách này giúp bạn không phải làm bẩn không gian toàn cầu. Điều này được ghi lại trong tài liệu AngularJS ở đây .

Cập nhật Fiddle của Matt Ball để sử dụng phương pháp này: http://jsfiddle.net/subhaze/a4Rc2/114/

Ví dụ đầy đủ:

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
của tôi đang trả về một lệnh gọi lại khác: angle.callbacks._0, tôi nên sửa lỗi này như thế nào?
raberana

@ eaon21 bạn có ví dụ fiddle không?
subhaze vào

2
@ eaon21 nó hành vi mong muốn, sản phẩm thay thế góc JSON_CALLBACK sang một dynamicly tạo ra, bạn không cần phải chú ý đến nó
Guillaume86

Và ví dụ bạn gọi Youtube api như thế nào?
Gino

Có vẻ như họ có lib phía máy khách của riêng mình để tương tác với API. Bất kỳ ví dụ nào bạn có có thể giúp thu hẹp những gì bạn đang cố gắng làm?
subhaze

69

Các điều quan trọng nhất tôi không hiểu cho một thời gian là yêu cầu phải chứa "callback = JSON_CALLBACK", bởi vì AngularJS đổi các địa chỉ yêu cầu , thay thế một định danh duy nhất cho "JSON_CALLBACK". Phản hồi của máy chủ phải sử dụng giá trị của tham số 'callback' thay vì mã hóa cứng "JSON_CALLBACK":

JSON_CALLBACK(json_response);  // wrong!

Vì tôi đang viết tập lệnh máy chủ PHP của riêng mình, tôi nghĩ rằng tôi biết tên hàm mà nó muốn và không cần phải chuyển "callback = JSON_CALLBACK" trong yêu cầu. Sai lầm lớn!

AngularJS thay thế "JSON_CALLBACK" trong yêu cầu bằng một tên hàm duy nhất (như "callback = angle.callbacks._0") và phản hồi của máy chủ phải trả về giá trị đó:

angular.callbacks._0(json_response);

2
Có cách nào chúng ta có thể thay đổi tên của lệnh gọi lại để nó hoạt động với jsontệp tĩnh được mã hóa cứng không .
Pavel Nikolov

9

Điều này rất hữu ích. Angular không hoạt động chính xác như JQuery. Nó có phương thức jsonp () của riêng nó, thực sự yêu cầu "& callback = JSON_CALLBACK" ở cuối chuỗi truy vấn. Đây là một ví dụ:

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

Sau đó, hiển thị hoặc thao tác {{data}} trong mẫu Angular của bạn.


4

Điều này sẽ hoạt động tốt cho bạn, miễn là hàm jsonp_callbackhiển thị trong phạm vi toàn cầu:

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

Bản demo đầy đủ: http://jsfiddle.net/mattball/a4Rc2/ (tuyên bố từ chối trách nhiệm: Tôi chưa từng viết bất kỳ mã AngularJS nào trước đây)


Điều đó đã làm được! Nó chỉ ra phạm vi mà tôi đã lộn xộn. Cảm ơn bạn!
akronymn

1
Câu trả lời này không hữu ích lắm. Nó không tuân theo phạm vi của AngularJS.
xil3

1
@ xil3 cảm ơn bạn đã phản hồi; tiếc là chỉ OP (akronymn) mới có thể chuyển đổi câu trả lời được chấp nhận, không phải tôi.
Matt Ball

@DanieleBrugnara vui lòng xem các bình luận trước cho câu trả lời này.
Matt Ball

4

Bạn vẫn cần thiết lập callbackcác thông số:

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

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

Trong đó 'functionName' là một tham chiếu được xâu chuỗi đến hàm được xác định chung. Bạn có thể xác định nó bên ngoài tập lệnh góc cạnh của mình và sau đó xác định lại nó trong mô-đun của bạn.


2

Để phân tích cú pháp, hãy làm điều này-

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

Hoặc bạn có thể sử dụng `$ scope.data = JSON.Stringify (data);

Trong mẫu Angular, bạn có thể sử dụng nó như

{{data}}

0

đối với tôi, các giải pháp trên chỉ hoạt động khi tôi thêm "format = jsonp" vào các tham số yêu cầu.


0

Tôi đang sử dụng góc 1.6.4 và câu trả lời do subhaze cung cấp không phù hợp với tôi. Tôi đã sửa đổi nó một chút và sau đó nó hoạt động - bạn phải sử dụng giá trị được trả về bởi $ domains.trustAsResourceUrl . Mã đầy đủ:

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);
    });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.