JSONP

Client

Pour des raisons de sécurité les requêtes Ajax ne peuvent être exécutée que sur le même domaine que la page d’appel. Essayez de faire une requête Ajax sur un serveur distant et vous obtiendrez rapidement une erreur de ce type : Access to restricted URI denied » code: « 1012″.

Pour palier ce problème il existe deux principales solutions. La première est d’utiliser du code au niveau serveur, PHP par exemple, pour faire la jonction entre le webservice et la requête Ajax. La requête Ajax appellera le script PHP sur le même domaine qui se chargera d’appeler à son tour le serveur distant. Ca fonctionne mais rend le script client dépendant du script serveur et demande de manipuler plusieurs langages et portions de code.

La seconde solution est de ruser et d’appeler le serveur distant par une balise HTML script qui lui n’a pas de limitation au niveau du domaine.

<script type="text/javascript" src="http://www.sitedistant.com/api.php?param=hello"> </script>

De cette manière, on accède aux informations JSON distantes mais deux problèmes se posent.
L’appel des webservices se fait généralement à un moment précis et non forcement à l’ouverture de la page. On devra passer par la création dynamique de la balise script au moment de l’appel. En voici la méthode.

<script type="text/javascript"> 
    script      = document.createElement("script");
    script.type = "text/javascript";
    script.src  = "http://www.sitedistant.com/api.php?param=hello";

    document.getElementsByTagName("head")[0].appendChild(script);
</script>

Le tag script est créé, pointant sur le serveur distant et inclus dans la balise head. Pour plus de confort, intégrons cette création de tag dans une fonction getRemoteDate(url) qui nous permettra d’appeler le script quand bon nous semblera.

<script type="text/javascript">

    function getRemoteData(url) {
        script      = document.createElement("script");
        script.type = "text/javascript";
        script.src  = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    }
    getRemoteData('http://www.sitedistant.com/api.php?param=hello');
</script>

Premier problème réglé.
Seulement, même ainsi inclus dans la page, du simple code JSON retourné ne produira aucun effet, voire une erreur. C’est là qu’entre en scène le JSONP (JSON with padding, c’est-à-dire préformaté). Le JSONP est une manière de formatter le JSON délivré par le serveur de webservice afin qu’il puisse être interprété et utilisé par le client. Généralement un paramètre callback est passé au serveur, lui indiquant le nom d’une fonction réceptrice. La fonction réceptrice est ajoutée et recevra les données du serveur distant.

<script type="text/javascript">
    function getRemoteData(url) {
        script      = document.createElement("script");
        script.type = "text/javascript";
        script.src  = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    }
    // la fonction réceptrice, ici "myFunction"
    function myFunction(response) {
        alert(response.data);
    }
    // le nom de la fonction réceptrice est passé en paramètre "callback"

    getRemoteData('http://www.sitedistant.com/api.php?param=hello&callback=myFunction');
</script>

Si le webservice supporte le JSONP tout se passera à merveille et les données seront reçues et passées à la fonction demandée, ici myFunction, et ainsi exécutée. Les principaux webservices actuels prennent cette méthode en compte, les webservices Google et Yahoo! entre autres.

Serveur

Rien de plus simple à intégrer. L’usage veut que le paramètre se nomme callback (ou jsonp sur certains services). Il suffit de prendre en compte ce paramètre et d’encapsuler les données JSON dans une fonction du même nom. Un cours exemple :

<?php
$json = "{ data: 'Plein de données utiles' }";
if (isset($_GET['callback'])) {
    echo $_GET['callback'].'('.$json.');';
} else {
    echo $json;
}

?>

Ce qui renverra soit :

{ data: 'Plein de données utiles' }

Soit les mêmes données dans la fonction demandée :

myFunction({ data: 'Plein de données utiles' });

Jquery

jQuery est une excellente librairie qui propose une fonction d’abstraction de requêtes Ajax. Ici rien de particulier à faire, la fonction Ajax peut être appelé de la même manière que le serveur soit distant ou nom.

<script type="text/javascript">
$(function() {
    $.ajax({
        dataType:'jsonp',
        url: 'http://www.monsitedistant.com/api.php',
        data: { param:'hello' },
            success:function(response) {
                alert("Réponse : "+ response.data);
            }
    });
});

</script>

Il suffira de préciser dataType:'jsonp' pour que jQuery se charge de faire tout le boulot précédemment décrit en toute discrétion :

  • > création et inclusion de la balise script
  • > création d’une fonction temporaire au nom unique de type jsonp1234567
  • > ajout automatique du paramètre callback=jsonp1234567 à la requête

Le principal problème est qu’il n’est possible que de faire des requêtes de type GET. Il est impossible de reproduire une méthode POST par ce système.


© 2010 www.askamail.com

Nous contacter | Plan du site | Conditions legales | Privacy Policy