Contoh dasar menggunakan .ajax () dengan JSONP?

187

Tolong bisakah seseorang membantu saya mencari tahu cara memulai JSONP?

Kode:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    var photos = function (data) {
     alert(data);
    };
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: false,
    });
});

Fiddle: http://jsfiddle.net/R7EPt/6/

Seharusnya menghasilkan peringatan, sejauh yang saya bisa dari dokumentasi: tidak (tapi juga tidak menghasilkan kesalahan).

Terima kasih.

simon
sumber
$ .ajax ({url: pm_url, dataType: 'jsonp', jsonpCallback: foto, jsonp: false,}); Anda telah memasukkan foto sebagai string.
wOlVeRiNe

Jawaban:

388

JSONP benar-benar hanya sebuah trik untuk mengatasi XMLHttpRequest kebijakan domain yang sama. (Seperti yang Anda ketahui, seseorang tidak dapat mengirim permintaan AJAX (XMLHttpRequest) ke domain lain.)

Jadi - alih-alih menggunakan XMLHttpRequest, kita harus menggunakan tag skrip HTMLl, yang biasanya Anda gunakan untuk memuat file JS, agar JS mendapatkan data dari domain lain. Kedengarannya aneh?

Masalahnya - ternyata tag skrip dapat digunakan dengan cara yang mirip dengan XMLHttpRequest ! Lihat ini:

script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data";

Anda akan berakhir dengan segmen skrip yang terlihat seperti ini setelah memuat data:

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

Namun ini agak merepotkan, karena kita harus mengambil array ini dari tag skrip . Jadi pembuat JSONP memutuskan bahwa ini akan bekerja lebih baik (dan memang demikian):

script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://www.someWebApiServer.com/some-data?callback=my_callback";

Perhatikan fungsi my_callback di sana? Jadi - ketika server JSONP menerima permintaan Anda dan menemukan parameter panggilan balik - alih-alih mengembalikan array JS biasa, ia akan mengembalikan ini:

my_callback({['some string 1', 'some data', 'whatever data']});

Lihat di mana keuntungannya: sekarang kita mendapatkan panggilan balik otomatis ( my_callback ) yang akan dipicu begitu kita mendapatkan data. Hanya itu yang perlu diketahui tentang JSONP : ini adalah tag panggilan balik dan skrip.


CATATAN:
Ini adalah contoh sederhana penggunaan JSONP, ini bukan skrip siap produksi.

Demonstrasi RAW JavaScript (umpan Twitter sederhana menggunakan JSONP):

<html>
    <head>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
        <script>
        function myCallback(dataWeGotViaJsonp){
            var text = '';
            var len = dataWeGotViaJsonp.length;
            for(var i=0;i<len;i++){
                twitterEntry = dataWeGotViaJsonp[i];
                text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
            }
            document.getElementById('twitterFeed').innerHTML = text;
        }
        </script>
        <script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
    </body>
</html>


Contoh jQuery dasar (umpan Twitter sederhana menggunakan JSONP):

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.ajax({
                    url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
                    dataType: 'jsonp',
                    success: function(dataWeGotViaJsonp){
                        var text = '';
                        var len = dataWeGotViaJsonp.length;
                        for(var i=0;i<len;i++){
                            twitterEntry = dataWeGotViaJsonp[i];
                            text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
                        }
                        $('#twitterFeed').html(text);
                    }
                });
            })
        </script>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
    </body>
</html>


JSONP adalah singkatan dari JSON dengan Padding . (teknik yang dinamai sangat buruk karena tidak ada hubungannya dengan apa yang oleh kebanyakan orang dianggap sebagai "bantalan".)

Orang itu
sumber
3
Jawaban ini sekarang agak ketinggalan zaman karena browser sekarang mendukung Access-Control-Allow-Originheader yang memungkinkan panggilan Ajax biasa dilakukan ke beberapa domain lintas-asal.
jfriend00
Ingatlah bahwa Anda tidak dapat melakukan formulir POST dengan JSONP. Info lebih lanjut di sini: markhneedham.com/blog/2009/08/27/…
thdoan
4
Apa yang harus Anda pertimbangkan jika Anda ingin skrip ini siap produksi?
Tamu
1
Wow, ini sangat membantu! Saya akhirnya mengetahui apa sebenarnya JSONP dan bagaimana cara kerjanya!
Jerry Liu
146

Bahkan ada cara yang lebih mudah untuk bekerja dengan JSONP menggunakan jQuery

$.getJSON("http://example.com/something.json?callback=?", function(result){
   //response data are now in the result variable
   alert(result);
});

Di ?akhir URL memberitahu jQuery bahwa itu adalah permintaan JSONP, bukan JSON. jQuery mendaftar dan memanggil fungsi panggilan balik secara otomatis.

Untuk detail lebih lanjut, lihat dokumentasi jQuery.getJSON .

Petr Peller
sumber
2
@PrpPeller, Kelihatannya bagus tapi saya sepertinya tidak membuat produk darinya. Bisakah kamu melihat ini? JSFiddle Tidak memberi tahu data. Mungkin saya melewatkan sesuatu
tika
@xDNP Respons JSONP harus didukung oleh server. Sever Anda sepertinya tidak mendukungnya karena saya tidak dapat melihat panggilan balik yang ditambahkan di sini: mylivecanvas.com/api/… . Anda juga harus menggunakan &callback=?karena ini bukan parameter pertama dalam kasus Anda.
Petr Peller
1
@PetrPeller Saya sangat tertarik dengan solusi Anda. Tapi, itu tidak berhasil pada saya. Saya tidak ingin memposting pertanyaan baru tetapi itu tidak membantu saya. Apa yang tampaknya tidak didukung oleh server ? Apa yang harus saya lakukan? Dan bisakah Anda memberi saya URL lengkap yang berfungsi untuk server saya? Aku akan berterima kasih padamu. Apakah saya memerlukan konfigurasi server?
tika
3
Apa yang diedit terakhir, "Tolong jangan gunakan jQuery lagi!" berarti?
ParkCheolu
1
Sekarang tahun 2018, dan saya tidak yakin apa yang seharusnya digunakan pada tahun 2017!
Vasily Hall
28

Menanggapi OP, ada dua masalah dengan kode Anda: Anda perlu mengatur jsonp = 'callback', dan menambahkan fungsi callback dalam variabel seperti Anda sepertinya tidak berfungsi.

Pembaruan: ketika saya menulis ini, Twitter API baru saja dibuka, tetapi mereka mengubahnya dan sekarang membutuhkan otentikasi. Saya mengubah contoh kedua menjadi contoh kerja (2014Q1), tetapi sekarang menggunakan github.

Ini tidak berfungsi lagi - sebagai latihan, lihat apakah Anda dapat menggantinya dengan API Github:

$('document').ready(function() {
    var pm_url = 'http://twitter.com/status';
    pm_url += '/user_timeline/stephenfry.json';
    pm_url += '?count=10&callback=photos';
    $.ajax({
        url: pm_url,
        dataType: 'jsonp',
        jsonpCallback: 'photos',
        jsonp: 'callback',
    });
});
function photos (data) {
    alert(data);
    console.log(data);
};

meskipun lansiran () ing array seperti itu tidak benar-benar berfungsi dengan baik ... Tab "Net" di Firebug akan menunjukkan kepada Anda JSON dengan benar. Trik berguna lainnya adalah melakukan

alert(JSON.stringify(data));

Anda juga dapat menggunakan metode jQuery.getJSON . Inilah contoh html lengkap yang mendapat daftar "inti" dari github. Dengan cara ini ia membuat fungsi callback yang dinamai secara acak untuk Anda, itulah yang terakhir "callback =?" di url.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>JQuery (cross-domain) JSONP Twitter example</title>
        <script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.getJSON('https://api.github.com/gists?callback=?', function(response){
                    $.each(response.data, function(i, gist){
                        $('#gists').append('<li>' + gist.user.login + " (<a href='" + gist.html_url + "'>" + 
                            (gist.description == "" ? "undescribed" : gist.description) + '</a>)</li>');
                    });
                });
            });
        </script>
    </head>
    <body>
        <ul id="gists"></ul>
    </body>
</html>
PapaFreud
sumber
2
Anda benar, itu tidak berfungsi lagi. Twitter mengubah API mereka.
PapaFreud
3
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<title>An JSONP example </title>
</head>
<body>
<!-- DIV FOR SHOWING IMAGES -->
<div id="images">
</div>
<!-- SCRIPT FOR GETTING IMAGES FROM FLICKER.COM USING JSONP -->
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
  format: "json"
},
//RETURNED RESPONSE DATA IS LOOPED AND ONLY IMAGE IS APPENDED TO IMAGE DIV
function(data) {
  $.each(data.items, function(i,item){
  $("<img/>").attr("src", item.media.m).appendTo("#images");

 });
});</script>
</body>
</html> 

Kode di atas membantu dalam mendapatkan gambar dari Flicker API. Ini menggunakan metode GET untuk mendapatkan gambar menggunakan JSONP. Ini dapat ditemukan secara detail di sini

Ganesh Babu
sumber