Ajax hors ligne avec Gears, tutoriel

Faire fonctionner Ajax hors ligne et utiliser le navigateur comme plateforme d'application est plutôt simple, pour cela on installe le plug-in Gears et on utilise les scripts de base inclus dans ce tutoriel comme point de départ.

Ce tutoriel est simplifié: notre première application affiche seulement le message "Salut le Monde!", mais elle le fait sans connexion Internet quand on tape l'URL de la page de démonstration...

Puis nous allons plus loin avec la galerie d'image hors ligne et plus tard nous verrons comment ajouter des boutons, des menus, des listes et tout autre widget...

IMPORTANT: Gears est une solution portable utilisable immédiatement, mais Google ayant décidé de se tourner vers HTML 5, pour un développement à long terme, il est préférable d'opter pour les API hors ligne de HTML 5.

Pourquoi Ajax hors ligne?

En utilisant Ajax hors ligne, il devient possible de se servir d'une pages web comme interface graphique pour un script fonctionnant localement. En fait comme nous l'expliquerons dans la seconde démonstration, le système devient un moyen d'installer des applications et de les mettre à jour instantanément, de façon très simplifiée.

Il est important que la même application fonctionne de façon réactive, que ce soit hors ligne ou en ligne, d'où l'intérêt de combiner ces deux technologies, Gears et Ajax.

Gears, présentation

Pour réaliser une application offline, il faut utiliser l'API Gears qui est téléchargée avec le plug-in.
Son architecture globale utilise les composants suivants:
- LocalServer, le serveur local de ressources, qui établit une synchronisation entre les données sur le serveur et la copie locale.
- Le Workerpool qui contrôle l'exécution du code JavaScript.
- Un module Desktop pour faire fonctionner l'application sur le bureau.
- Une base de donnée SQLite pour réproduire le contenu d'une base SQL sur le serveur.
- Une bibliothèque JavaScript qui inclut XMLHttpRequest et une horloge.
En outre un module de géolocalisation adapte l'application aux pays.

Pour une présentation plus générale du plugin, voir Google Gears.

Comment utiliser Gears

L'utilisateur doit télécharger et installer le plugin (sauf sous Chrome où il est intégré) pour que le site visité utilise Gears.
Quand le plug-in est installé et que l'internaute visite un site qui supporte cette option, il lui est demandé s'il veut que le site utilise Gears et ainsi active la sauvegarde des données localement.
Par la suite, le visiteur pourra continuer à voir le contenu de ce site, en l'état ou il est au moment de la connexion, sur son navigateur et sans Internet. Par exemple consulter le contenu de sa boite aux lettres tel qu'il était au moment de la connexion.
Si l'on change quelque chose sur son compte, les modifications seront propagée sur le site lors de la prochaine connexion.
Des services comme Docs de Google peuvent donner accès à cette option de façon automatique.

Structure d'une page Gears

Une page Gears doit inclure quelques scripts et éventuellement disposer d'une zone pour afficher les informations sur l'état de Gears.

Inclusion des scripts

<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript" src="gears_offline.js"></script>
<script type="text/javascript" src="ajax-gears.js"></script>

gears_init.js initialise Gears, mais ne prépare pas le mode hors ligne.
gears_offline.js initialise le mode hors ligne ou retourne en ligne en proposant le choix à l'utilisateur, il est associé aux boutons.
ajax-gears.js est notre script pour combiner Ajax et Gears.

Corps de la page

<body>
   <div id="textOut"></div>
   <button onClick="createStore()"> Se mettre hors ligne </button>
<button onClick="removeStore()"> Revenir en ligne </button> </body>

La page contient deux boutons. Il appellent les fonctions createStore() et removeStore() pour passer en mode déconnecté ou revenir en mode connecté. Le champ textOut affiche les message concernant l'état de Gears.

Option: Puisque nous avons ajouté un script, nous avons choisi d'initialiser Gears en appelant la fonction init() à partir de celui-ci, sinon il faudrait ajouter un attribut à la balise <body>:

<body onload="init">  

Mode hors ligne automatique

On peut lancer la fonction createStore() directement après l'initialisation de Gears, et supprimer les deux boutons, ainsi l'application fonctionnera toujours hors ligne. Mais si l'on veut pouvoir mettre à jour les scripts et autres ressources, les boutons sont nécessaires.

Le code Gears

Le fichier gears_init.js est fourni par Google et le programmeur n'a pas besoin de s'en soucier.
Le fichier gears_offline.js est une version modifiée du fichier go_offline.js de Google.

Fonctions et variables de gears_offline.js

init()

Elle crée un espace de stockage local géré par Gears.

createStore()

Elle stocke les documents localement. Elle dépend du fichier manifeste qui indique la liste des fichiers et scripts concernés.

removeStore()

Elle redirige l'internaute sur le site en ligne et supprime l'espace local.

Outre ces fonctions, le fichier contient les variables STORE_NAME et MANIFEST_FILENAME. La seconde contient le nom du fichier manifest, pas défaut manifest.json.

Le fichier manifest.json

Dans l'exemple, il contient les lignes suivantes:

{
"betaManifestVersion": 1,
"version": "1.0",
"entries": [
{ "url": "ajax-hors-ligne-demo.html"},
{ "url": "gears_offline.js"},
{ "url": "gears_init.js"},
{ "url": "ajax-gears.js"}
]
}

Les URLs sont celles de l'application web, en l'occurence une simple page de démonstration, et les scripts. Tout autre fichier nécessaire à l'application doit y être mentionné.

Le code Ajax

Lorsque Gears est installé, le code Ajax utilisé est celui qui est inclut dans le framework Gears. Sinon on doit revenir à un code Ajax classique utilisant l'objet XMLHttpRequest reconnu pas le navigateur.

Pour ce faire on définit une fonction qui crée une instance selon l'objet disponible et selon le navigateur:

function gearsCreate()
{
     var xhr = google.gears.factory.create('beta.httprequest');
     if(!xhr)
     {
         try  {   xhr = new ActiveXObject('Msxml2.XMLHTTP');   }
         catch (err1) 
         {
               try { xhr = new ActiveXObject('Microsoft.XMLHTTP');  }
               catch (err2) 
               {
                  try  {  xhr = new XMLHttpRequest();   }
                  catch (err3) 
                  {
                     xhr = false;
                  }
               }
         }
   }
   return xhr;
}  

Quand aux attributes et méthodes de l'objet, celles de Gears, XMLHttpRequest ou d'ActiveX, sont les mêmes et le reste du code est donc commun aux trois cas.

Exemple d'utilisation de GET

On charge un fichier au format texte dont le nom est "xhr-demo.txt".

var xhr = createXHR();
xhr.open('GET', "xhr-demo.txt");
xhr.onreadystatechange = function() 
{
      if (xhr.readyState == 4) 
      {
           alert(xhr.responseText);
      }
};
xhr.send();
  

L'appel à createXHR crée une instance d'objet Gears/XMLHttpRequest/ActiveX assignée à la variable xhr.
Le contenu du fichier est chargé dans xhr.responseText et on l'affiche dans une boite d'alerte.

Démonstration minimale avec la méthode GET

Pour commencer simplement, on définit une application Ajax qui charge juste le contenu d'un fichier avec la méthode GET et affiche le contenu dans la page.

On utilise les fonction createXHR() et une fonction gearsGet() qui reprend le code précédent, mais à laquelle on donne en paramètres le nom du fichier à charger et le nom d'une fonction qui traite le contenu de ce fichier une fois chargé.

function gearsGet(xhr, fun, filename)
{ 
     xhr.open('GET', filename);
     xhr.onreadystatechange = function() 
     {
         if (xhr.readyState == 4) 
         {
               fun(xhr.responseText);
         }
     };
    xhr.send();
}
function storing(result)
{
     var storage = document.getElementById("storage");
     storage.innerHTML = result;
}
function demo()
{
     init();  // starts gears
     var xhr = gearsCreate();    // creates an XHR object 
     gearsGet(xhr, storing, 'xhr-demo.txt');    // loads a file on the server
}   

window.onload=demo;

La fonction demo() initialise Gears, crée une instance et appelle la fonction gearsGet() avec en paramètre le nom d'un fichier à charger et celui de la fonction storing pour traiter le contenu.

Le fonction storing() affiche le contenu du fichier dans une zone de la page dédiée à cela dont l'ID est storage.

Galerie de robots hors ligne

Cette démonstration qui affiche une galerie de photos est le début d'une application Web hors ligne et aussi le début d'une nouvelle façon d'installer des logiciels sur le bureau.
Voici comment fonctionneront les applications dans un futur proche:

  1. On se connecte au site du distributeur.
  2. On place la page de l'application en bookmark.
  3. On demande à passer en mode hors ligne ce qui commande à Gears de copier localement tous les fichiers et scripts de l'application. En l'occurence les photos de la galerie et les scripts d'affichage.
  4. On peut ensuite accéder à la galerie à tout moment en cliquant sur le lien en bookmark.
  5. Pour mettre à jour la galerie, on repasse en mode en ligne, et on revient en mode hors ligne pour une nouvelle synchronisation qui remplace et ajoute des fichiers.

En fait cela équivaud à aller sur le site du distributeur et télécharger un logiciel, avec l'avantage d'une mise à jour simplifiée.

Le développeur doit placer dans le fichier manifeste la liste de toutes les images de la galerie. Nous avons renommé le fichier gallery.json.

Il faut aussi changer le nom assigné à la variable MANIFEST_FILENAME dans le fichier gears_offline.js. Mais il n'est pas nécessaire de modifier le fichier, il suffit de réassigner la variable dans le script propre à l'application, gallery.js.

Cette application utilise Ajax pour charger en mémoire les images pendant que l'utilisateur regarde les photos et ainsi supprime le temps d'attente. Le temps d'attente est minime lorsque l'application est hors ligne, mais notre application doit fonctionner à la fois hors connexion et sur le Web.

Le script appelle la fonction preloading() pour chaque image de la galerie, elle charge l'image de façon asynchone et est déclenchée au chargement de la page.

La fonction enlarge() affiche l'image en grand format dans un <div> dédié à cela, nommé bigview.

function enlarge(element)
{
  var name = element.src;
 
  name = localFilename(name);
  name = name.slice(6);   // remove the "thumb-" part
  name = "robots/" + name;  // restore path 
 
  var str = "<img src='" + name + "' >";
  document.getElementById("bigview").innerHTML = str;
}

La fonction demo() utilise le script gallery.js

function demo()
{
    MANIFEST_FILENAME = "galerie.json";		// changing manifest file
    init();           // starts gears 
    preloading("robots/asimo.jpg");
    preloading("robots/manoi.jpg");
    preloading("robots/nao.jpg");
    preloading("robots/robonova.jpg");
    preloading("robots/repliee.jpg");
}

window.onload=demo;   // launched when the page is displayed

Démonstration et téléchargements

Problèmes et limitations

Effacer la mémoire tampon en cas de problème. Sous Firefox, aller dans Outils -> Effacer mes traces -> Cocher Cache. Décocher éventuellement les autres données mémorisées si on ne veut pas les effacer. Puis valider.
Pour Internet Explorer on peut passer par le panneau de configuration du système d'exploitation.

Quand un document est hors-ligne, il devient impossible au développeur de mettre à jour les ressources concernées par l'application. Elle sont chargées sur le serveur mais ne peuvent être téléchargées. Il faut revenir hors ligne pour rendre accessible les versions modifiées.

Les deux démos ont été testées et elle fonctionnent, mais si vous avez plusieurs applications hors ligne en même temps, elle pourraient ne pas fonctionner.

La méthode POST d'Ajax pourrait fonctionner, mais les scripts PHP coté serveur pour traiter les données reçues ne sont pas synchronisés par Gears, l'application ne fonctionnerait qu'en ligne comme le précise la FAQ de gears.

Outils et références