Web Avancé

Luc Brun

Plan

Les cookies

Utilisation des cookies

Positionnement des cookies

Positionnement des cookies

Options des cookies

Set-Cookie: name=value; expires=date; path=/; domain=www.greyc.ensicaen.fr
Un cookie est identifié par le triplé nom/chemin/domaine => différents cookies de même nom.

Options des cookies (détails)

Set-Cookie: name=value; expires=date; path=/; domain=www.greyc.ensicaen.fr

Cookies et Shell : Un exemple

#!/bin/sh
expires=`date -d '+1 hour'  +"%a, %d-%b-%Y %T GMT"`
echo "Content-type: text-html"
echo "Set-Cookie: seen=yes;expires=$expires"
echo ""
echo "<html><head><title>Hello</title></head><body><h1>"
if echo $HTTP_COOKIE | grep -q seen
then
    echo "Je vous ai déja vu quelque part"
else
    echo "Hello Etranger"
fi
echo "</h1></body></html>"

Lecture d'un cookie en schell

#!/bin/sh
get_val()
{
        name=$1
	if [ "$HTTP_COOKIE" = "" ]
	then
		echo
		return -1
	fi
	ifs=$IFS
	IFS=";"
	set $HTTP_COOKIE
	IFS=$ifs
	for egal in $*
	do
		var=`echo $egal | cut -d"=" -f1`
		if [ $var = $name ]
		then
			echo $egal | cut -d"=" -f2
			return 0
		fi
	done
	echo ""
	return -2
}

Cookies en PHP

Cookies en PHP: Exemple

<?php 
setcookie("seen", "yes", time()+3600);
?>

<html>
<head><title>Hello</title></head>
<body><h1>
<?
if(isset($_COOKIE["seen"]))
   echo "Je vous ai déja vu quelque part";
else
   echo "Hello Etranger";
?>
</h1>
</body>
</html>

Cookies en Javascript

Cookies en Javascript: Exemple

<script language="Javascript">
var seen=true;
if((document.cookie.length==0)||(document.cookie.indexOf("seen=")==-1))
{
    document.write("Hello Etranger!");
    seen=false;
}
date=new Date();
date.setTime(date.getTime()+60*60*1000);
document.cookie="seen=yes; expires="+date.toGMTString()+"; path=/";
if(seen)
document.write("Je vous ai déjà vu quelque part..");
</script>

Lecture, écriture de Cookies en Javascript

function createCookie(name,value,days,hours) {
	if (days||hours) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000)+(hours*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

Définition de données persistantes

Méthode par champs caché

Un site de démonstration utilisant ce système est disponible ici.

Les sessions PHP

Démarage d'une session

  bool session_start  ( void  )

Si la clé est transmise par cookie, le start_session doit être positionné avant toute balise HTML

Positionnement des variables : $_SESSION.

Les fonctions isset, unset

isset et unset permettent respectivement de déterminer si une variable est positionné et de la supprimer. Dans le cadre des sessions :
  • isset($_SESSION['pizza'])
    permet de savoir si la variable pizza est positionné dans la session.
  • unset($_SESSION['pizza'])
    permet de supprimer pizza de la liste des variables de la session.
  • void session_unset ( void )
    supprime toutes les variables de la session.
  • Fin de sessions

    bool session_destroy(void)
    

    Fin de sessions : Example

    <?php
    // Initialize the session.
    // If you are using session_name("something"), don't forget it now!
    session_start();
    
    // Unset all of the session variables.
    $_SESSION = array();
    
    // If it's desired to kill the session, also delete the session cookie.
    // Note: This will destroy the session, and not just the session data!
    if (isset($_COOKIE[session_name()])) 
        setcookie(session_name(), '', time()-42000, '/');
    
    // Finally, destroy the session.
    session_destroy();
    ?>
    

    AJAX

    AJAX(Asynchronous Javascript and Xml) est une méthode permettant d'interroger un serveur http a partir d'un navigateur et du language Javascript. Son avantage est de permettre une plus grande réactivité de l'interface par rapport au web classique.

    Cette partie du cours est inspirée des cours de :

    un ciment de technologies existantes ?

    AJAX est constitué d'une combinaison de technologies existantes. Un schéma classique d'utilisation est le suivant:
    1. Un utilisateur exécute une action
    2. l'action appelle une fonction Javascript qui envoie une requête à un serveur
    3. le serveur traite la requête et renvoie une réponse au format texte ou XML
    4. la réponse est récupérée par une fonction Javascript qui va modifier le document HTML en jouant sur les propriétés CSS ou sur le contenu HTML du site en utilisant DOM (voir + loin).

    XmlHttpRequest

    AJAX est basé sur la classe javascript XMLHttpRequest. A l'origine un objet ActiveX introduit par Microsoft dans IE5 puis repris par les autres navigateurs en tant qu'objet Javascript. Microsoft a suivi depuis IE7. Un objet XMLHttpRequest:

    Création d'un objet XmlHttpRequest

    D'autre part certains navigateurs exigent que le type de données utilisé par le serveur soit du text/xml. On peut forcer ce type par la fonction overrideMimeType('text/xml'). Une fonction résumant l'ensemble de ces contraintes est disponible ici (source P. Loisel).

    Propriétés de XMLHttpRequest

  • readyState
    voir les valeurs
  • onreadystatechange
    nom de la fonction callback à exécuter lorsqu'il y a un changement d'état de l'objet
  • status
    le code HTTP renvoyé par la requête
  • statusText
    la chaîne correspondant au code HTTP
  • responseText
    réponse au format texte
  • responseXML
    réponse au format XML
  • Méthodes de XMLhttpRequest

  • open( String method , String url, asynFlag )
    initialisation de la requête
  • method
    GET ou POST
  • url
    url à déclencher
  • asynFlag
    synchrone ou asynchrone
  • overrideMimeType( String mimetype )
    force le type MIME de la réponse
  • send(Variant body)
    Envoi de la requête (null en get ou données en post)
  • setRequestHeader( String header, String value )
    en-tête HTTP à envoyer
  • Un premier exemple (simple)

    On utilise une méthode GET, en mode synchrone, avec une réponse de type text.
        <script type="text/javascript" src="ajax.js">
        </script>
        <script type="text/javascript">
          function sendRequest(url)
          {
          var requeteHttp=getRequestHttp();
          if(requeteHttp==null)
          {
          alert("Impossible d'utiliser Ajax sur ce navigateur");
          }
          else
          {
        requeteHttp.open('GET',url,false);
          requeteHttp.send(null);
          if(requeteHttp.readyState==4) // requete achevé. Résultat transmis
          {
          if(requeteHttp.status==200)// fin correcte de la requete
        alert(requeteHttp.responseText);      //affichage du message
          else
          alert("Error :"+requeteHttp.status+",La requete ne s'est pas correctement executée");
          }
          }
          return true;
          }
        </script>
      </head>
    
      <body>
        <h1>Page 1 Ajax</h1>
    
        <a href="#" onclick="return sendRequest('page2.php?messg=coucou');"> requete</a>
    
    
    

    Remarques et démonstrations

    Démonstration

    Modification du contenu d'une balise.

    Appels Asynchrones(1/2)

    Appels Asynchrones (2/2)

    Passage d'arguments en mode POST

    XML et DOM

    XML(eXtensible Markup Language)

    DOM (Document Object Model)

    DOM: Les noeuds (Méthodes)

  • Node insertBefore(in Node newChild, in Node refChild) provoque(DOMException);
    Insère le noeud newChild avant le noeud enfant refChild (si ce dernier existe). Si refChild est null, alors newChild est inséré à la fin de la liste des enfants. Retourne le noeud inséré.
  • Node replaceChild(in Node newChild, in Node oldChild) provoque(DOMException);
    Remplace le noeud enfant oldChild par newChild dans la liste des enfants, et retourne le noeud oldChild. Si le newChild est déjà dans l'arbre, il en est d'abord retiré. Retourne le noeud remplacé.
  • Node removeChild(in Node oldChild) provoque(DOMException)
    Retire le noeud enfant oldChild de la liste des enfants, et le retourne.
  • Node appendChild(in Node newChild) provoque(DOMException);
    Ajoute le noeud newChild à la fin de la liste des noeuds enfants du noeud courant. Si newChild est déjà dans l'arbre, il est d'abord retiré. Retourne le noeud ajouté.
  • boolean hasChildNodes();
    C'est une méthode pratique qui permet de savoir si un noeud a des enfants. Retourne true si le noeud a un enfant, false sinon.
  • Node cloneNode(in boolean deep);
    Retourne un clone de ce noeud, c'est à dire, qu'elle est utilisée comme constructeur générique pour copier des noeuds Le noeud cloné n'a pas de parent (c'est à dire que si on lui applique la méthode parentNode la valeur retournée est null.). Si le paramètre deep est true, la méthode clone récursivement le sous-arbre du noeud spécifié. Sinon elle ne clone que le noeud lui-même (et ses attributs, si c'est un noeud de type Element). Retourne le noeud dupliqué.
  • DOM: Les NodeList

    DOM: Les attributs

    nomTypeModifiable Description
    nameChaîneNon Retourne le nom de l'attribut courant.
    specifiedbooleenNon Prend la valeur true si une valeur a été explicitement donnée à l'attribut courant dans le document original ; false sinon.
    valueChaîneOui A l'utilisation, la valeur de l'attribut est retournée comme une chaîne de caractères. Les entités caractères et les entités générales de référence sont remplacées par leurs valeurs.

    DOM : Les éléments

  • DOMString getAttribute(in DOMString name);
    Permet d'obtenir une valeur d'attribut à partir du nom de l'attribut. Retourne la valeur de l'attribut
  • void setAttribute(in DOMString name, in DOMString value) provoque (DOMException);
    Ajoute un nouvel attribut. Si un attribut de même nom existe déjà au niveau de l'élément, sa valeur est changée par celle passée en paramètre. Ne retourne rien.
  • void removeAttribute(in DOMString name) provoque (DOMException);
    Supprime un attribut spécifié par son nom. Si l'attribut supprimé a une valeur par défaut, il est alors immédiatement remplacé.
  • Attribut getAttributeNode(in DOMString name);
    Permet d'obtenir un noeud de type Attr à partir de son nom. Retourne le noeud de type Attr dont le nom est celui spécifié ou null si il n'y a pas d'attribut de ce nom.
  • Attribut setAttributeNode(in nouvelAttribut) provoque (DOMException);
    Rajoute un nouvel attribut. Si un attribut de ce nom est déjà présent dans l'élément, il est remplacé par le nouveau. Si le nouvel attribut newAttr remplace un attribut existant de même nom, le noeud attribut Attr précédemment existant est retourné, sinon la valeur null est retournée.
  • Attribut removeAttributeNode(in oldAttribut) provoque (DOMException);
    Supprime l'attribut spécifié. Retourne le noeud qui a été supprimé.
  • NodeList getElementsByTagName(in DOMString name);
    Retourne une liste de noeuds (NodeList) de tous les éléments descendant ayant un nom donné, organisés selon l'ordre dans lequel ils pourraient apparaître dans un parcours préfixé de l'arbre des objets
    fonction très utile.
  • DOM: Document

  • Element createElement(in DOMString tagName) provoque (DOMException);
    Crée un élément du type spécifié. Notez que l'instance retournée implémente l'interface Element, donc les attributs peuvent être spécifiés directement sur l'objet retourné. Retourne le nouvel objet.
  • Text createTextNode(in DOMString data);
    Crée un noeud Text contenant la chaîne de caractères spécifiée. Retourne le nouvel objet Text.
  • Attr createAttribute(in DOMString Name) provoque (DOMException);
    Crée un objet Attr d'un nom donné. Notez que l'instance de l'objet Attr peut ensuite être rattachée à un Element en utilisant la méthode setAttribute.
  • NodeList getElementsByTagName(in DOMString tagName);
    Retourne un objet NodeList (une liste de noeuds) de tous les objets Elements ayant un nom de balise donné, laquelle est ordonnée selon l'ordre de lecture prédéfini de l'arbre du Document.
  • DOM: NameNodeMap

    Représente une collection de noeuds non ordonnés. Son unique attribut length représente le nombre d'éléments.
  • Node getNamedItem(in DOMString name);
    Permet d'obtenir un noeud à partir de son nom.
  • Node setNamedItem(in noeud arg) provoque(DOMException);
    Ajoute un noeud en utilisant son attribut nodeName. Notez que plusieurs noeuds d'un même type ne peuvent pas être stockés puisque leurs noms rentreraient alors en collision
  • Node removeNamedItem(in DOMString name) provoque (DOMException);
    Retire un noeud spécifié par son nom. Si le noeud retiré est de type Attr ayant une valeur par défaut, il est immédiatement remplacé. Retourne le noeud retiré de la table des noeuds nommés ou la valeur null si aucun noeud de ce nom n'existe dans cette table.
  • Node item(in unsigned long index);
    Retourne l'élément à la position index du NameNodeMap. Si la valeur de index est supérieure ou égale au nombre de noeuds de la table, la valeur retournée est null.
  • Un premier exemple (simple)

    ...requeteHttp.onreadystatechange=function(){afficher_alert(requeteHttp);};... 
    et
    function afficher_alert(requeteHttp)
    {
        var hotels=requeteHttp.responseXML.getElementsByTagName("hotel");
        for(i=0;i<hotels.length;i++)
    	{
    	    var hotel=hotels.item(i);
    	    var prix =hotel.getAttributeNode("prix").value;
    	    //	    var name=hotel.getElementsByTagName("name").item(0).firstChild.nodeValue;
    	    var name=hotel.childNodes.item(1).firstChild.nodeValue;
    	    var tel=hotel.getElementsByTagName("tel").item(0).firstChild.nodeValue;
    
    	    alert("prix="+prix+"name="+name+"tel="+tel);
    	}
    }
    

    Un second exemple (pas très propre)

    function afficher_alert2(requeteHttp)
    {
        var hotels=requeteHttp.responseXML.getElementsByTagName("hotel");
        var obj=document.getElementById("answer1");
        obj.innerHTML="

    Un dernier exemple

    function afficher_table(requeteHttp)
    {
        var titles=Array("Prix","Nom","Tel");
        var values=Array();
        var hotels=requeteHttp.responseXML.getElementsByTagName("hotel");
        var obj=document.getElementById("answer");
        var table=document.createElement("table");
        var oldTables=obj.getElementsByTagName("table");
        if(oldTables.length==1)
    	obj.replaceChild(oldTables.item(0),table);
    
        table.setAttribute("border","1");
        var tr=document.createElement("tr");
        var td;
        for(i=0;i<3;i++)
    	{
    	    td=document.createElement("td");
    	    td.appendChild(document.createTextNode(titles[i]));
    	    tr.appendChild(td);
    	}
        table.appendChild(tr);
        for(i=0;i<hotels.length;i++)
    	{
    	    var hotel=hotels.item(i);
    	    values[0] = hotel.getAttributeNode("prix").value;
    	    values[1] = hotel.getElementsByTagName("name").item(0).firstChild.nodeValue;
    	    values[2] = hotel.getElementsByTagName("tel").item(0).firstChild.nodeValue;
    	    tr=document.createElement("tr");
    
    	    for(j=0;j<3;j++)
    		{
    		    td=document.createElement("td");
    		    td.appendChild(document.createTextNode(values[j]));
    		    tr.appendChild(td);
    		}
    	    table.appendChild(tr);
    	}
        obj.appendChild(table);
    }
    

    Un dernier exemple (Exemple)

    Les flux RSS

    Définition d'un flux RSS

    Contenu d'un flux RSS

    Autres balises: author : mail de l'auteur, category : Associe l'item à une catégorie ; comments : URL d'une page de commentaire en rapport avec l'item.

    DTD d'un RSS et Exemple

  • DTD
    Voir le code suivant
  • Exemple
    Voir le code suivant
  • Génération de Flux RSS: Un exemple

    header('Content-type: application/atom+xml');
    $dbconn=connexion();
    function display_news($query,$i)
    {
        echo "item\n";
    
        echo "title".pg_fetch_result($query,$i,2)."/title\n";
        echo "description".pg_fetch_result($query,$i,3)."/description\n";
        echo "pubDate".pg_fetch_result($query,$i,1)."/pubDate\n";
        echo "link".pg_fetch_result($query,$i,4)."/link\n";
    
        echo "/item\n";
    }
    echo '?xml version="1.0" encoding="utf-8"?';
    ?>
    
    rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    channel
    titleIAPR TC 15 RSS/title
    descriptionIAPR TC15 news /description
    image
            urlhttp://www.greyc.ensicaen.fr/iapr-tc15/images/gbr_logo.jpg/url
            linkhttp://www.greyc.ensicaen.fr/iapr-tc15//link
        /image 
    <?
      $requete="select date of last update"; $query=pg_query($dbconn,$requete);
    
    echo "lastBuildDate".pg_fetch_result($query,0,0)."/lastBuildDate\n";
    pg_free_result($query);
    ?>
    
    linkhttp://www.greyc.ensicaen.fr/iapr-tc15/rss.php/link
    <?
    $requete="select features of news order by date desc"; $query=pg_query($dbconn,$requete);
    if(!$query){  echo "Query error :".$requete;  exit;}
    for($i=0;$i<pg_num_rows($query);$i++)
      display_news($query,$i);
    pg_free_result($query);pg_close($dbconn);
    /channel/rss
    
    That's all folks.