Exemple basique d'utilisation de .ajax () avec JSONP?

187

Quelqu'un pourrait-il m'aider à trouver comment démarrer avec JSONP?

Code:

$('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,
    });
});

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

Devrait produire une alerte, pour autant que je sache à partir de la documentation: n'est pas (mais ne produit aucune erreur non plus).

Merci.

Simon
la source
$ .ajax ({url: pm_url, dataType: 'jsonp', jsonpCallback: photos, jsonp: false,}); Vous aviez saisi des photos sous forme de chaîne.
wOlVeRiNe

Réponses:

388

JSONP est vraiment une astuce simple pour surmonter la même politique de domaine XMLHttpRequest . (Comme vous le savez, on ne peut pas envoyer de requête AJAX (XMLHttpRequest) à un domaine différent.)

Donc, au lieu d'utiliser XMLHttpRequest, nous devons utiliser des balises HTMLl de script , celles que vous utilisez habituellement pour charger des fichiers JS, afin que JS obtienne des données d'un autre domaine. Cela semble bizarre?

La chose est - il s'avère que les balises de script peuvent être utilisées d'une manière similaire à XMLHttpRequest ! Regarde ça:

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

Vous vous retrouverez avec un segment de script qui ressemble à ceci après avoir chargé les données:

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

Cependant, c'est un peu gênant, car nous devons récupérer ce tableau à partir de la balise de script . Alors JSONP créateurs ont décidé que cela fonctionnera mieux (et il est):

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

Remarquez la fonction my_callback là-bas? Ainsi, lorsque le serveur JSONP reçoit votre demande et trouve le paramètre de rappel - au lieu de renvoyer un tableau JS brut, il renvoie ceci:

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

Voyez où est le profit: maintenant nous obtenons un rappel automatique ( my_callback ) qui sera déclenché une fois que nous aurons obtenu les données. C'est tout ce qu'il y a à savoir sur JSONP : c'est un rappel et des balises de script.


REMARQUE:
ce sont des exemples simples d'utilisation de JSONP, ce ne sont pas des scripts prêts pour la production.

Démonstration RAW JavaScript (simple flux Twitter utilisant 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>


Exemple jQuery de base (flux Twitter simple utilisant 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 signifie JSON with Padding . (technique très mal nommée car elle n'a vraiment rien à voir avec ce que la plupart des gens pourraient considérer comme un «rembourrage».)

Ce mec
la source
3
Cette réponse est maintenant quelque peu obsolète car les navigateurs prennent désormais en charge les en- Access-Control-Allow-Origintêtes qui permettent d'effectuer des appels Ajax réguliers vers certains domaines d'origine croisée.
jfriend00
Gardez à l'esprit que vous ne pouvez pas créer de formulaire POST avec JSONP. Plus d'infos ici: markhneedham.com/blog/2009/08/27/…
thdoan
4
Que devez-vous prendre en compte si vous souhaitez que ces scripts soient prêts pour la production?
invité le
1
Wow, c'est vraiment utile! J'arrive enfin à savoir ce qu'est exactement JSONP et comment ça marche!
Jerry Liu
146

Il existe un moyen encore plus simple de travailler avec JSONP en utilisant jQuery

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

Le ?à la fin de l'URL indique à jQuery qu'il s'agit d'une requête JSONP au lieu de JSON. jQuery enregistre et appelle la fonction de rappel automatiquement.

Pour plus de détails, reportez-vous à la documentation jQuery.getJSON .

Petr Peller
la source
2
@PetrPeller, ça a l'air génial mais je ne semble pas en faire un produit. Pouvez-vous voir cela une fois? JSFiddle Il n'alerte aucune donnée. Peut-être que j'ai raté quelque chose
tika
La réponse @xDNP JSONP doit être prise en charge par le serveur. Votre serveur ne semble pas le supporter car je ne vois aucun rappel supplémentaire ici: mylivecanvas.com/api/… . Vous devez également utiliser &callback=?car ce n'est pas le premier paramètre dans votre cas.
Petr Peller
1
@PetrPeller Je suis très intéressé par votre solution. Mais cela ne fonctionne pas sur moi. Je ne veux pas publier de nouvelle question mais cela ne m'aide pas. Que ne semble pas prendre en charge par le serveur signifie? Que devrais-je faire? Et pouvez-vous me donner une URL complète qui fonctionne pour mon serveur? Je vous en serais reconnaissant. Ai-je besoin d'une configuration de serveur?
tika
3
Que signifie la dernière modification, "Veuillez ne plus utiliser jQuery!" signifier?
ParkCheolu
1
Nous sommes maintenant en 2018, et je ne suis pas sûr de ce qui est censé être utilisé en 2017!
Vasily Hall
28

En réponse à l'OP, il y a deux problèmes avec votre code: vous devez définir jsonp = 'callback', et l'ajout d'une fonction de rappel dans une variable comme vous ne semblez pas fonctionner.

Mise à jour: quand j'ai écrit cela, l'API Twitter était juste ouverte, mais ils l'ont changée et elle nécessite maintenant une authentification. J'ai changé le deuxième exemple en un exemple fonctionnel (2014Q1), mais en utilisant maintenant github.

Cela ne fonctionne plus - comme un exercice, voyez si vous pouvez le remplacer par l'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);
};

bien qu'alerter () un tableau comme celui-là ne fonctionne pas vraiment bien ... L'onglet "Net" de Firebug vous montrera correctement le JSON. Une autre astuce pratique consiste à faire

alert(JSON.stringify(data));

Vous pouvez également utiliser la méthode jQuery.getJSON . Voici un exemple html complet qui obtient une liste de "gists" de github. De cette façon, il crée une fonction de rappel nommée aléatoirement pour vous, c'est le dernier "callback =?" dans l'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
la source
2
Tu as raison, ça ne marche plus. Twitter a changé son API.
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> 

Le code ci-dessus aide à obtenir des images de l'API Flicker. Cela utilise la méthode GET pour obtenir des images à l'aide de JSONP. Il peut être trouvé en détail ici

Ganesh Babu
la source