Le but de cet article est de vous familiariser avec la notion de script CGI en Rebol. Vous verrez qu'il est très facile de réaliser un premier script Rebol dès que vous disposez d'un serveur et que vous avez installé une version de Rebol. Vous apprendrez ainsi à dynamiser vos pages HTML, mais aussi à les enrichir et les rendre interactives par l'incorporation de code JavaScript.
Deux types essentiels de besoins n'ont pas de solution avec le HTML :
Pour répondre à ces deux besoins, il a fallu compléter les pages HTML statiques avec divers types de portions de programmes, que ce soit du côté client ou du côté serveur. Les solutions sont aujourd'hui nombreuses : JavaScript, applet ou servlet Java, JSP, ASP... Mais la plus ancienne solution fût le CGI.
Le langage de programmation des CGI est à priori quelconque, il suffit qu'il puisse être exécutable ou interprétable par le système d'exploitation du serveur, qu'il sache gérer les flux d'entrée/sortie de données, qu'il permette de manipuler les chaînes de caractères, et qu'il soit interfaçable éventuellement avec des bases de données. Parmi les langages utilisés pour réaliser des applications CGI, on peut citer classiquement le C, C++, Java ou encore des langages de script tels que Perl et Rebol.On parle alors de scripts CGI.
Le principe de fonctionnement est simple. Un exécutable CGI est lancé par le serveur à la suite d'une requête http, et son résultat est de générer une nouvelle page web à renvoyer au navigateur afin d'être affichée. En fonction de l'extension du fichier CGI demandé (.exe, .cgi, .r, .pl, .html, ...), le serveur activera le logiciel associé pour son exécution ou son interprétation (C, C++, Java, Rebol, ...).
Prenons l'exemple suivant. Un client saisit son login et son mot de passe en remplissant dans son navigateur le formulaire chargé avec la page HTML statique ci-dessous.

Le code correspondant est :
<HTML> <HEAD><TITLE>Ma page de connexion INDEX.HTML</TITLE></HEAD> <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman"> <FORM NAME="identification" METHOD="GET" ACTION="menu.cgi"> <DIV ALIGN="center"> <H2>Bienvenue</H2> <TABLE BORDER=0 WIDTH=450> <TR><TD>Login</TD> <TD><INPUT TYPE="text" NAME="login" SIZE="20" MAXLENGTH="20"></TD></TR> <TR><TD>Mot de passe</FONT></TD> <TD><INPUT TYPE="password" NAME="motpasse" SIZE="20" MAXLENGTH="10" VALUE=""></TD></TR> </TABLE> <BR> <INPUT TYPE="submit" VALUE="Connexion"> </DIV> </FORM> </BODY> </HTML> |
Lorsque l'utilisateur valide son formulaire en cliquant sur le bouton de type "submit", le serveur http répond à cette requête en exécutant le programme "menu.cgi" avec les paramètres reçus. Dans notre exemple sont utilisés deux paramètres nommés "login" et "motpasse".
La cinquième ligne de l'exemple pourra s'écrire en fonction des deux cas :
<FORM NAME="identification" METHOD="GET" ACTION="menu.cgi"> |
ou
<FORM NAME="identification" METHOD="POST" ACTION="menu.cgi"> |
Avec la méthode GET, la transmission des paramètres se fait en utilisant l'URL et les valeurs transmises sont accessibles par le serveur via les variables d'environnement et sont visibles dans l'URL.
Avec la méthode POST, la transmission des paramètres se fait en utilisant le périphérique d'entrée standard du serveur, les valeurs transmises sont y sont récupérées à partir du flux de données. Contrairement à la méthode précédente, la transmission des paramètres est plus discrète car les valeurs transmises ne sont plus visibles dans l'URL et la taille des informations transmises n'est pas limitée.
Par exemple si le login saisi est la chaîne de caractères "alpha" et le mot de passe "beta", l'URL associé à la page renvoyée par le script "menu.cgi" est :
Les variables QUERY-STRING, CONTENT-LENGTH et CONTENT-TYPE, renseignent respectivement sur la chaîne d'informations transmise, sur sa longueur en nombre d'octets et sur le type de données associées selon le format MIME. Le format MIME, rappelons-le, est le mode de codage utilisé par les navigateurs afin de régler le problème d'incompatibilité lié aux caractères spéciaux, aux accents et aux caractères de ponctuation.
Un exemple de données au format MIME est le texte récupéré par le serveur :
La règle appliquée sur le flux de sortie est q'un CGI commence toujours par préciser dans l'en-tête HTTP le type MIME pour que le navigateur sache quel type de contenu doit il afficher : fichier HTML (CONTENT-TYPE: text/html), fichier ASCII (CONTENT-TYPE: text/plain), image GIF (CONTENT-TYPE: image/gif), image JPG (CONTENT-TYPE: image/gpg), animation QUICKTIME (CONTENT-TYPE: video/quicktime), document RTF (CONTENT-TYPE: application/rtf), fichier son (CONTENT-TYPE: audio/basic)...
A chaque validation de formulaire, le serveur charge et exécute un script CGI.
Notre script est un fichier exécutable (menu.cgi) écrit en langage Rebol, mais qu'est-il censé faire ?
Après avoir récupéré les données transmises, le script doit être capable de les traiter, notamment par l'intermédiaire des manipulations d'accès à une base de données, mais pas nécessairement : un exemple de script pourrait être l'affichage d'un calendrier hebdomadaire en fonction d'une date saisie.
Tout script CGI, par contre, est censé renvoyer comme résultat une nouvelle page qui deviendra la nouvelle page chargée dans le navigateur du client.
Notre programme Rebol pourra ressembler à :
REBOL [ title: "menu.cgi" description : "Mon premier script CGI en Rebol" ] ; --- Récupération des paramètres en fonction de la méthode GET ou POST utilisée dans le formulaire --- if error? try [ methode: system/options/cgi/request-method either methode = "GET" [ ; --- Si les données sont envoyées avec la méthode GET, on lit la variable d'environnement QUERY-STRING --- data: system/options/cgi/query-string ] [ ; --- Si la méthode est POST, on lit le flux d'entrée sur le périphérique d'entrée standard, on utilise la variable CONTENT-LENGTH pour connaître le nombre d'octets que nous avons à lire --- data: copy "" len: to-integer system/options/cgi/content-length until [ buffer: copy "" read-io system/ports/input buffer (to-integer system/options/cgi/content-length) append data buffer len: length? (head data) ( (length? data) = len) ] ] ; --- "data" contient la chaîne de caractères des données récupérées au format MIME --- query: make object! decode-cgi data ; --- Le mot "decode-cgi" de Rebol, permet de transcrire la chaîne lue en construisant un objet dont les propriétés sont les différents champs du formulaire --- ] [ ; --- Erreur lors de la récupération des paramètres --- ; --- Pour débuter l'affichage de la page résultat, on doit indiquer qu'il s'agit d'une page html --- print "Content-Type: Text/html^/" ; --- Tout ce qui est écrit en sortie standard avec le mot "print" de Rebol, ira vers la page résultat --- print { <HTML> <HEAD></HEAD> <BODY BGCOLOR="#c0ffff"> <DIV ALIGN="center"> <H2>IMPOSSIBLE DE RECUPERER LA SAISIE DU LOGIN !</H2> </DIV> </BODY> </HTML> } quit ; --- Interruption de l'exécution du script --- ] ; --- Ici nous pouvons traiter les paramètres reçus dont les valeurs sont "query/login" et "query/motpasse" --- ; .................................. ; --- Ici nous pouvons définir la page à afficher page: { <HTML><HEAD><TITLE>Ma page générée par le script menu.cgi</TITLE></HEAD> <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman"> <DIV ALIGN="center"> <H2>MENU PRINCIPAL</H2> <BR> <H5><A HREF="achat.cgi">Consulter les achats</A></H5> <H5><A HREF="vente.cgi">Consulter les ventes </A></H5> <H5><A HREF="reserver.cgi?login=MON_LOGIN">Réserver</A></H5> <A HREF="index.html"><IMG SRC="gif/reconnexion.jpg"></A> </DIV> </BODY> </HTML> } ; --- Affichage de la page résultat --- print "Content-Type: Text/html^/" print page |
La page générée ressemblera alors à :

La fonction JavaScript permettant de le faire est "alert()". Il suffit de l'appeler dans un bloc "<SCRIPT>...</SCRIPT>" de la page HTML.
La déclaration de la page à afficher deviendra :
page: { <HTML> <HEAD><TITLE>Ma page générée par le script menu.cgi</TITLE></HEAD> <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman"> <DIV ALIGN="center"> <H2>MENU PRINCIPAL</H2> <BR> <H5><A HREF="achat.cgi">Consulter les achats</A></H5> <H5><A HREF="vente.cgi">Consulter les ventes </A></H5> <H5><A HREF="reserver.cgi?login=MON_LOGIN">Réserver</A></H5> <A HREF="index.html"><IMG SRC="gif/reconnexion.jpg"></A> </DIV> </BODY> <!-- Ligne insérée --> <SCRIPT LANGUAGE="javascript"> alert("Connexion réussie.") </SCRIPT> </HTML> } |
Le résultat de cette modification est l'apparition à l'écran de la boite suivante :

On peut rende cette page encore plus interactive. On va pour cela y intégrer 6 cases à cocher (balise HTML <CHECKBOX>). Chacune des cases peut être saisie séparément, mais nous souhaitons pouvoir cocher ou décocher les 6 cases en un seul clic sur un bouton "Tout cocher" ou un bouton "Tout décocher".
Nous avons besoin de passer par un formulaire qui englobera l'ensemble des champs INPUT : CHECKBOX (cases à cocher) et BUTTON (boutons). Les 3 options de menus ne sont plus des liens HREF, elles deviennent aussi des boutons INPUT. Le script "traiter_choix.cgi"permettra après validation de traiter les cases cochées en fonction de l'option de menu choisie. Notre page est rendue un peu plus interactive par l'association de deux fonctions JavaScript "cocher()" et "decocher()" aux événements clic sur le bouton "Tout cocher" et sur "Tout décocher". Vous constaterez que la déclaration de ces fonctions apparaît dans le bloc <HEAD> car tout appel d'une fonction JavaScript doit être précédé par sa déclaration.
Enfin, une autre forme d'exemple d'utilisation de code JavaScript est la portion nous permettant d'afficher la date et l'heure (en rouge) dans le menu.
La description de la page affichée est transformée et devient :
page: { <HTML><HEAD><TITLE>Ma page générée par le script menu.cgi</TITLE> <!-- Déclaration des fonctions JavaScript --> <SCRIPT LANGUAGE="javascript"> // -- Ma fonction cocher() function cocher() { MonFormulaire.c1.checked = true ; MonFormulaire.c2.checked = true ; MonFormulaire.c3.checked = true ; MonFormulaire.c4.checked = true ; MonFormulaire.c5.checked = true ; MonFormulaire.c6.checked = true ; } // -- Ma fonction decocher() function decocher() { MonFormulaire.c1.checked = false ; MonFormulaire.c2.checked = false ; MonFormulaire.c3.checked = false ; MonFormulaire.c4.checked = false ; MonFormulaire.c5.checked = false ; MonFormulaire.c6.checked = false ; } </SCRIPT> </HEAD> <BODY BGCOLOR="YELLOW" TEXT="BLACK" FACE="times new roman"> <DIV ALIGN="center"> <H2>MENU PRINCIPAL</H2> <H3><FONT COLOR="red"> Nous sommes le <!-- Code JavaScript pour affichage de la date du jour --> <script language="JavaScript"> var aujourd_hui = new Date(); document.write(aujourd_hui.getDate()+' '); document.write(aujourd_hui.getMonth()+1+'/'); document.write(aujourd_hui.getFullYear()); </script> - il est <!-- Code JavaScript pour affichage de l'heure --> <script language="JavaScript"> var monHeure = new Date(); document.write(monHeure.getHours()+'h '); document.write(monHeure.getMinutes()+'mn '); </script> </FONT></H3> <BR> <!-- Les options de menu sont englobées dans un formulaire et traitées par un seul script "traiter_choix.cgi" --> <FORM NAME="MonFormulaire" METHOD="POST" ACTION="traiter_choix.cgi"> <!-- Tableau des cases à cocher --> <TABLE BORDER=1 BGCOLOR="cyan"> <TR><TD COLSPAN=2 BGCOLOR="white" ALIGN=center> <FONT SIZE=4>Sélection du type d'immobilier</FONT></TD> </TR> <TR><TD><INPUT TYPE="checkbox" NAME="c1">Appartement</TD> <TD><INPUT TYPE="checkbox" NAME="c2">Bingalot</TD> </TR> <TR><TD><INPUT TYPE="checkbox" NAME="c3">Garage</TD> <TD><INPUT TYPE="checkbox" NAME="c4">Local commercial</TD> </TR> <TR><TD><INPUT TYPE="checkbox" NAME="c5">Maison, villa</TD> <TD><INPUT TYPE="checkbox" NAME="c6">Terrain</TD> </TR> <TR><TD COLSPAN=2 ALIGN=center><FONT SIZE=4> <!-- Association des fonctions JavaScript à l'événement clic sur le bouton INPUT --> <INPUT TYPE="button" VALUE="Tout cocher" ONCLICK=cocher()> <INPUT TYPE="button" VALUE="Tout décocher" ONCLICK=decocher()> </FONT></TD> </TR> </TABLE> <BR> </FORM> <BR> <!-- Les 3 options de menus ne sont plus des liens HREF mais des boutons INPUT --> <INPUT TYPE="button" NAME="achat" VALUE="Consulter les achats"> <INPUT TYPE="button" NAME="vente" VALUE="Consulter les ventes"> <INPUT TYPE="button" NAME="reserve" VALUE="Réservation"> <BR><BR><BR> <A HREF="index.html"><IMG SRC="reconnexion.jpg"></A> </DIV> </BODY> <!-- Ligne insérée précédemment --> <SCRIPT LANGUAGE="javascript">alert("Connexion réussie.")</SCRIPT> </HTML> } |
Voici ce que générera le programme entier "menu.cgi" sous un navigateur :

Les inconvénients par contre, sont ceux que l'on reproche aux script CGI de manière générale, à savoir :
A vous de vous amusez maintenant...
CGI :
HTML :
JavaScript :
Noureddine Akhamlich