การแยกวิเคราะห์การตอบสนอง JSONP $ http.jsonp () ใน angular.js


112

ฉันใช้$http.jsonp()คำขอของเชิงมุมซึ่งส่งคืน json ที่ห่อด้วยฟังก์ชันได้สำเร็จ:

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

จะเข้าถึง / แยกวิเคราะห์ฟังก์ชันที่ห่อหุ้ม - JSON ได้อย่างไร


4
ด้วย JSONP คุณจะไม่ "เข้าถึง / แยกวิเคราะห์ฟังก์ชันที่ห่อหุ้มด้วย JSON" โทรกลับของคุณถูกเรียก ได้รับข้อมูล JSON เป็นอาร์กิวเมนต์
Matt Ball

ฉันได้ลองทำสิ่งที่ชอบ
Akronymn

(ขออภัยกดเข้าเร็วเกินไปด้านบน) การโทรกลับของฉันถูกเรียกว่าเมื่อใด ข้อมูลโค้ดจะมีประโยชน์มาก ฉันได้ลองทำสิ่งต่างๆมากมาย ณ จุดนี้และฉันก็นิ่งงัน
akronymn

การโทรกลับจะถูกเรียกเมื่อมีการตอบกลับ คุณมีฟังก์ชันที่ชื่อjsonp_callback? ถ้าไม่แสดงว่าเป็นปัญหาของคุณ
Matt Ball

สำหรับตอนนี้ฉันได้เขียนฟังก์ชั่นง่ายๆเพื่อส่งคืนองค์ประกอบแรกของ json function jsonp_callback(data) { return data.found; //should be 3 }
akronymn

คำตอบ:


300

อัปเดต: ตั้งแต่ Angular 1.6

คุณไม่สามารถใช้สตริง JSON_CALLBACK เป็นตัวยึดสำหรับระบุตำแหน่งที่ค่าพารามิเตอร์การเรียกกลับได้อีกต่อไป

ตอนนี้คุณต้องกำหนดการเรียกกลับดังนี้:

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

เปลี่ยน / เข้าถึง / ประกาศพารามิเตอร์ผ่าน$http.defaults.jsonpCallbackParamค่าเริ่มต้นเป็นcallback

หมายเหตุ: คุณต้องตรวจสอบให้แน่ใจว่า URL ของคุณถูกเพิ่มในรายการที่เชื่อถือได้ / รายการที่อนุญาตพิเศษ:

$sceDelegateProvider.resourceUrlWhitelist

หรือเชื่อถือได้อย่างชัดเจนผ่านทาง:

$sce.trustAsResourceUrl(url)

success/errorถูกเลิกใช้

$httpวิธีการดั้งเดิมสัญญาsuccessและerrorได้รับการเลิกใช้แล้วและจะถูกลบออกใน v1.6.0 ใช้วิธีมาตรฐานแล้วแทน หาก$httpProvider.useLegacyPromiseExtensionsมีการตั้งค่าแล้ววิธีการเหล่านี้จะโยนfalse$http/legacy error

ใช้:

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

คำตอบก่อนหน้า: Angular 1.5.x และก่อนหน้า

สิ่งที่คุณควรต้องทำคือเปลี่ยนcallback=jsonp_callbackเป็นcallback=JSON_CALLBACKชอบ:

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

จากนั้น.successฟังก์ชั่นของคุณควรเริ่มทำงานเหมือนที่คุณมีหากการส่งคืนสำเร็จ

การทำเช่นนี้จะช่วยให้คุณไม่ต้องทำให้พื้นที่ทั่วโลกสกปรก นี้ถูกบันทึกไว้ในเอกสาร AngularJS ที่นี่

อัปเดตซอของ Matt Ball เพื่อใช้วิธีนี้: http://jsfiddle.net/subhaze/a4Rc2/114/

ตัวอย่างเต็ม:

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
ของฉันกำลังส่งคืนการเรียกกลับที่แตกต่างกัน: angular.callbacks._0 ฉันจะแก้ไขสิ่งนี้ได้อย่างไร
raberana

@ eaon21 มีตัวอย่างซอไหม
subhaze

2
@ eaon21 มันเป็นพฤติกรรมที่ต้องการการแทนที่เชิงมุม JSON_CALLBACK เป็นสิ่งที่สร้างขึ้นแบบไดนามิกคุณไม่ต้องสนใจมัน
Guillaume86

และคุณเรียก Youtube api ได้อย่างไร?
Gino

ดูเหมือนว่าพวกเขามี lib ฝั่งไคลเอ็นต์ของตัวเองสำหรับโต้ตอบกับ API คุณมีตัวอย่างที่สามารถช่วย จำกัด สิ่งที่คุณกำลังพยายามทำได้หรือไม่?
subhaze

69

สิ่งที่สำคัญที่สุดผมไม่เข้าใจสำหรับค่อนข้างสักครู่ก็คือว่าการร้องขอจะต้องมี "โทรกลับ = JSON_CALLBACK" เพราะ AngularJS ปรับเปลี่ยน URL ของคำขอแทนตัวระบุเฉพาะสำหรับ "JSON_CALLBACK" การตอบสนองของเซิร์ฟเวอร์ต้องใช้ค่าของพารามิเตอร์ "เรียกกลับ" แทนการเข้ารหัส "JSON_CALLBACK" อย่างหนัก:

JSON_CALLBACK(json_response);  // wrong!

เนื่องจากฉันเขียนสคริปต์เซิร์ฟเวอร์ PHP ของตัวเองฉันคิดว่าฉันรู้ว่ามันต้องการชื่อฟังก์ชันอะไรและไม่จำเป็นต้องส่ง "callback = JSON_CALLBACK" ในคำขอ ความผิดพลาดครั้งใหญ่!

AngularJS แทนที่ "JSON_CALLBACK" ในคำขอด้วยชื่อฟังก์ชันเฉพาะ (เช่น "callback = angular.callbacks._0") และการตอบสนองของเซิร์ฟเวอร์จะต้องส่งคืนค่านั้น:

angular.callbacks._0(json_response);

2
มีวิธีใดบ้างที่เราสามารถเปลี่ยนชื่อการเรียกกลับเพื่อให้ทำงานกับjsonไฟล์คงที่แบบฮาร์ดโค้ดได้
Pavel Nikolov

9

สิ่งนี้มีประโยชน์มาก Angular ไม่ทำงานเหมือนกับ JQuery มีเมธอด jsonp () ของตัวเองซึ่งต้องใช้ "& callback = JSON_CALLBACK" ต่อท้ายสตริงข้อความค้นหา นี่คือตัวอย่าง:

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

จากนั้นแสดงหรือจัดการ {{data}} ในเทมเพลต Angular ของคุณ


4

สิ่งนี้น่าจะใช้ได้ดีสำหรับคุณตราบใดที่ฟังก์ชันjsonp_callbackนี้ปรากฏในขอบเขตส่วนกลาง:

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

การสาธิตแบบเต็ม: http://jsfiddle.net/mattball/a4Rc2/ (ข้อจำกัดความรับผิดชอบ: ฉันไม่เคยเขียนโค้ด AngularJS มาก่อน)


นั่นมัน! ปรากฎว่าขอบเขตที่ฉันสับสน ขอบคุณ!
akronymn

1
คำตอบนี้ไม่เป็นประโยชน์มากนัก ไม่เป็นไปตามขอบเขตของ AngularJS
xil3

1
@ xil3 ขอบคุณสำหรับคำติชม; น่าเสียดายที่มีเพียง OP (Akronymn) เท่านั้นที่สามารถเปลี่ยนคำตอบที่ยอมรับได้ไม่ใช่ฉัน
Matt Ball

@DanieleBrugnara โปรดดูความคิดเห็นก่อนหน้านี้สำหรับคำตอบนี้
Matt Ball

4

คุณยังต้องตั้งค่าcallbackในพารามิเตอร์:

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

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

โดยที่ 'functionName' เป็นการอ้างอิงแบบสตริงไปยังฟังก์ชันที่กำหนดโดยส่วนกลาง คุณสามารถกำหนดมันนอกสคริปต์เชิงมุมของคุณแล้วกำหนดใหม่ในโมดูลของคุณ


2

สำหรับการแยกวิเคราะห์ให้ทำเช่นนี้ -

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

หรือคุณสามารถใช้ `$ scope.data = JSON.Stringify (data);

ในเทมเพลต Angular คุณสามารถใช้เป็นไฟล์

{{data}}

0

สำหรับฉันวิธีแก้ปัญหาข้างต้นใช้งานได้เพียงครั้งเดียวที่ฉันเพิ่ม "format = jsonp" ในพารามิเตอร์คำขอ


0

ฉันใช้เชิงมุม 1.6.4 และคำตอบจากsubhazeไม่ได้ผลสำหรับฉัน ผมปรับเปลี่ยนมันเล็กน้อยและจากนั้นก็ทำงาน - คุณจะต้องใช้ค่าส่งกลับโดย$ sce.trustAsResourceUrl รหัสเต็ม:

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);
    });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.