Interactions entre l’homme et la machine sur le Web dynamique :¶
Lors de la navigation sur le Web, les internautes interagissent avec leur machine par le biais des pages Web.
L’Interface Homme-Machine (IHM) repose sur la gestion d’événements associés à des éléments graphiques munis de méthodes algorithmiques.
On parle de pages Web dynamique lorsque certaines de ces méthodes algorithmiques sont exécutées sur un serveur pour produire un résultat dans le navigateur coté client...
Notion de Client/Serveur ?¶
A faire vous même :
Lire la page Modèle client/serveur proposée par David ROCHE puis répondre aux questions suivantes :
Lorsque vous saisissez l'adresse http://jupyterhub.ecmorlaix.fr:8093 (10.1.3.50) dans Safari sur votre tablette iPad, indiquer qui alors est le client et qui est le serveur ?
- Client : Mon iPad (safari)
- Serveur : server du lycee qui gere le jupyterhub
- Si vous faites une publication locale de votre site web sur votre iPad, depuis l'application iSH Shell (ou a-Shell mini) en saisissant :
python3 -m http.server # à saisir depuis le dossier clone
indiquer qui est le client et qui est le serveur lorsque dans le navigateur de votre iPad, vous entrez l'URL :
http://127.0.0.1:8000?- Client : lipad (safari)
- Serveur : lipad
indiquer qui est le client et qui est le serveur lorsque depuis un navigateur d'une autre machine, vous entrez l'URL :
http://<IP_de_votre_iPad>:8000?- Client : mon ipad
- Serveur : IP de votre ipad (lipad qui heberge le server)
http, https, kesako ?¶
A faire vous même :
Lire la page Protocole HTTP proposée par David ROCHE puis répondre aux questions suivantes :
- Que signifie l'acronyme HTTP ?
Hypertext Transfer Protocol
- Quelle méthode HTTP permet au client de demander une ressource au serveur ?
get
- Quelle méthode HTTP permet au client de soumettre des données au serveur ?
post
- Quelle est la principale différence entre HTTPS et HTTP ?
HTTPS est plus securise et crypté (compte bancaire, mail). alors que http non (site ou on est pas log)
Un serveur Web avec Flask :¶
Flask) est un micro-framework Python, un module qui va nous permettre, en seulement quelques lignes de code, de créer un serveur HTTP en Python.
Dans un premier temps nous utiliserons Glitch pour éditer et héberger nos serveurs Flask.
Exercice 0 : Hello World¶
A faire vous même :
Remixer le projet https://glitch.com/~glitch-flask-python3 et renommer le avec votre prénom au format
prenom-1nsi-ecmorlaix-flask-ex0.Tester en cliquant sur le bouton
Showle bon fonctionnement de votre serveur Web puis copier/coller un lien vers votre projet dans le code Python de la cellule suivante pour l'intégrer dans ce notebook :
%%HTML
<center>
<iframe src="https://alan-1nsi-ecmorlaix-flask-ex0.glitch.me" width=70% height="500" ></iframe>
</center>
Observer les fichiers contenus dans ce projet :
README.mddécrit en markdown l'objet du projet ;glitch.jsondonne les instructions à la machine virtuelle (Container) mise à disposition par Glitch pour la configurer et exécuter le fichierserveur.py;requirements.txtindique les modules Python à installer sur la VM ;serveur.pycontient le code Python de notre serveur HTTP.Observer plus particulièrement le contenu de ce dernier fichier :
from flask import Flaskpermet d'importer le module Flask ;app = Flask(__name__)crée un objet Flask nommé app ;"@app.route("/")"ceci est un décorateur, celà signifie que la fonction
hello()qui suit ce décorateur sera appelée dans le cas où le serveur web recevra une requête HTTP avec une URL correspondant à la racine du site (/)def hello(): return "<h1>Demat d'an holl, ... ;<br><br>Kenavo !</h1>"
A l'appel de la fonction
hello(), le serveur renvoie vers le client une page HTML contenant la chaine de caractères"<h1>Demat d'an holl, ... ;<br><br>Kenavo !</h1>".app.run()cette instruction lance le serveur Flask
A coder vous même :
Modifier le contenu HTML renvoyé par votre serveur Web (soyez créatif !)...
A coder vous même :
- Modifier le fichier
serveur.pypour ajouter une route telle que :@app.route('/autre') def autre(): return "<h1>Mon autre page Web</h1>"
- Tester le bon fonctionnement de votre serveur Web en cliquant sur le bouton
Showet en tapant l'URL/autredans la barre d'adresse...
A coder vous même :
Modifier le contenu HTML renvoyé par votre serveur Web pour ajouter des hyperliens permettant de naviguer d'une page à l'autre dans votre site Web...
Ajouter un lien vers une route non définie...
Partager votre site avec d'autres élèves puis, dans Glitch, cliquer sur le bouton
Toolspuis sur le boutonLogspour visualiser les requètes successives que reçoit votre serveur... Répondre alors aux questions suivantes :quelle méthode ?
quel protocole ?
que signifie le 200 ? Code 200 : Page traité avec succès
- que signifie le 404 ? Code 404: erreur de chargement
Écrire tout le code HTML qui devra être renvoyé au client dans le programme Python n'est pas très pratique, Flask propose une autre solution bien plus satisfaisante : les templates...
Exercice 1 : les templates¶
A faire vous même :
Remixer votre précédent projet et renommer le avec votre prénom au format
prenom-1nsi-ecmorlaix-flask-ex1.Créer un répertoire
templatescontenant un fichierindex.html:
Pour le faire en ligne de commande, cliquer sur le bouton
Tools, puis sur le boutonLogs, puis sur le boutonConsole, et enfin saisir :$ mkdir templates $ cd templates $ touch index.html $ refreshIl faut systématiquement finir par une commande
refreshpour que les modifications effectuées enConsolesoient synchronisées dans l'éditeur graphique.
Copier/coller le code HTML suivant dans le fichier
index.html:<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8" /> <title>Accueil</title> </head> <body> <h1>Mon super site</h1> </body> </html>
Copier/coller le code Python suivant dans le fichier
serveur.py:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index() :
return render_template("index.html")
app.run()
- Tester en cliquant sur le bouton
Showle bon fonctionnement de votre serveur Web puis copier/coller un lien vers votre projet dans le code Python de la cellule suivante pour l'intégrer dans ce notebook :
%%HTML
<center>
<iframe src="https://alan-1nsi-ecmorlaix-flask-ex1.glitch.me/" width=70% height="500" ></iframe>
</center>
Le serveur renvoie maintenant au client la page HTML correspondant au fichier "index.html" qui a été créé dans le répertoire "templates". Attention, les fichiers HTML devront systématiquement se trouver dans un répertoire nommé "templates".
Pour l'instant notre site est statique : la page reste identique, quelles que soient les actions des visiteurs.
Flask permet de créer des pages dynamiques :
- le client (le navigateur web) envoie une requête HTTP vers un serveur web
- en fonction de la requête reçue et de différents paramètres, Flask "fabrique" une page HTML différente
- le serveur web associé à Flask envoie la page nouvellement créée au client
- une fois reçue, la page HTML est affichée dans le navigateur web
A faire vous même :
- Modifier le fichier
serveur.pytel que :
from flask import Flask, render_template
import datetime
app = Flask(__name__)
@app.route('/')
def index():
date = datetime.datetime.now()
h = date.hour
m = date.minute
s = date.second
return render_template("index.html", heure = h, minute = m, seconde = s)
app.run()
import datetimepermet d'importer le module datetime ;
date = datetime.datetime.now()récupère la date et l'heure courante dans date ;
h = date.hour m = date.minute s = date.secondAprès l'exécution des 3 lignes ci-dessus, les variables h, m et s contiennent l'heure courante.
render_template("index.html", heure = h, minute = m, seconde = s)La fonction
render_templatecontient 3 paramètres de plus par rapport à l'exemple précédent : le paramètre "heure", le paramètre "minute" et le paramètre "seconde", nous allons retrouver ces 3 paramètres dans le fichier HTML.
- Modifier le fichier
index.htmltel que :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Accueil</title>
</head>
<body>
<h1>Mon super site</h1>
<hr>
<p> Il est {{heure}} h {{minute}} min et {{seconde}} sec</p>
<hr>
</body>
</html>
- Tester ces modifications...
Nous avons bien une page dynamique, puisqu'à chaque fois que vous actualisez la page dans votre navigateur, l'heure courante du serveur s'affiche : à chaque fois que vous actualisez la page, vous effectuez une nouvelle requête et en réponse à cette requête, le serveur envoie une nouvelle page HTML (Vérifier les requètes dans
Logs)Attention, il est bien important de comprendre que la page HTML envoyée par le serveur au client ne contient plus les paramètres {{heure}}, {{minute}} et {{seconde}}. Au moment de créer la page, le serveur remplace ces paramètres par les valeurs passées en paramètres de la fonction
render_template(Vérifier en affichant le code source de la page (F12)).Le fichier
index.htmlne contient donc pas du HTML (même si cela ressemble beaucoup à du HTML), car les paramètres {{heure}}, {{minute}} et {{seconde}} n'existent pas en HTML. Le fichierindex.htmlcontient en fait un langage de template nommé Jinja). Jinja ressemble beaucoup au HTML, mais il rajoute beaucoup de fonctionnalités par rapport au HTML (notamment les paramètres entourés d'une double accolade comme {{heure}}). Si vous utilisez Jinja seul (sans un framework comme Flask), les paramètres ne seront pas remplacés et votre navigateur affichera "Il est {{heure}} h {{minute}} min et {{seconde}} sec".
A coder vous même :
- rendre dynamique votre projet Web de sorte qu'il affiche l'age exacte qu'aurait aujourd'hui la personnalité que vous présentez puis l'intégrer ci-dessous :
%%HTML
<center>
<iframe src="https://alan-1nsi-ecmorlaix-flask-ex1.glitch.me" width=70% height="500" ></iframe>
</center>
Pour intégrer des fonctionnalités statiques (CSS et JavaScript) à votre projet il faut placer vos fichiers
style.cssetscript.jsdans un nouveau dossier nomméstatic.Par conséquence, les liens d'accès à ces ressources CSS et JavaScript doivent être modifiés dans le fichier
index.htmldu dossiertemplatesSi les noms de répertoire
templatesetstaticne vous conviennent pas vous pouvez les renommer à votre guise, par exempleviewsetpublicmais il faut les déclarer dans l'instruction de création de l'objet Flaskapptel queapp = Flask(__name__, static_folder='public', template_folder='views')
Exercice 2 : Formulaire et Données¶
A faire vous même :
Remixer votre précédent projet et renommer le avec votre prénom au format
prenom-1nsi-ecmorlaix-flask-ex2-post.Modifier le fichier
index.htmlavec votre prénom tel que :
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Mon formulaire</title>
</head>
<body>
<form action="https://prenom-1nsi-ecmorlaix-flask-ex2-post.glitch.me/resultat" method="post">
<label>Nom</label> : <input type="text" name="nom" />
<label>Prénom</label> : <input type="text" name="prenom" />
<input type="submit" value="Envoyer" />
</form>
</body>
</html>
- Créer un fichier
resultat.htmldans le dossiertemplates:
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Résultat</title>
</head>
<body>
<h3>Bonjour {{prenom}} {{nom}}, j'espère que vous allez bien.</h3>
</body>
</html>
- Modifier le fichier
serveur.pytel que :
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/resultat',methods = ['POST'])
def resultat():
result = request.form
n = result['nom']
p = result['prenom']
return render_template("resultat.html", nom=n, prenom=p)
app.run()
- Tester en cliquant sur le bouton
Showle fonctionnement de votre serveur Web, vérifier les requètes dansLogs, puis copier/coller un lien vers votre projet dans le code Python de la cellule suivante pour l'intégrer dans ce notebook :
%%HTML
<center>
<iframe src="https://alan-1nsi-ecmorlaix-flask-ex2-post.glitch.me/" width=70% height="500" ></iframe>
</center>
Si vous saisissez, par exemple, HOPPER et Grace dans les champs Nom et Prénom du formulaire, qu'obtennez-vous après avoir appuyé sur le bouton Envoyer ?
Bonjour Grace HOPPER, j'espère que vous allez bien.
Analyse des évènements :¶
Nous effectuons une requête HTTP avec l'URL /, le serveur génère une page web à partir du fichier index.html, cette page, qui contient un formulaire (balise <form action="https://prenom-1nsi-ecmorlaix-flask-ex2-post.glitch.me/resultat" method="post">) est envoyée vers le client. On remarque 2 attributs dans cette balise form : action="https://prenom-1nsi-ecmorlaix-flask-ex2-post.glitch.me/resultat" et method="post". Ces 2 attributs indiquent que le client devra effectuer une requête de type POST (la méthode POST a déjà été vue dans la partie consacrée au protocole HTTP) dès que l'utilisateur appuiera sur le bouton Envoyer. Cette requête POST sera envoyée à l'URL https://prenom-1nsi-ecmorlaix-flask-ex2-post.glitch.me/resultat (voir l'attribut action). Les données saisies dans le formulaire seront envoyées au serveur par l'intermédiaire de cette requête.
Vous avez sans doute remarqué que la méthode à employer pour effectuer la requête HTTP n'est pas précisée dans le "@app.route('/')". Si rien n'est précisé, par défaut, c'est la méthode GET qui est utilisée.
Intéressons-nous à la fonction resultat(), puisque c'est cette fonction qui sera exécutée côté serveur pour traiter la requête POST :
def resultat():
result = request.form
n = result['nom']
p = result['prenom']
return render_template("resultat.html", nom=n, prenom=p)
request.form est un dictionnaire Python qui a pour clés les attributs name des balises input du formulaire (dans notre cas les clés sont donc nom et prenom) et comme valeurs ce qui a été saisi par l'utilisateur. Si l'utilisateur saisit HOPPER et Grace, le dictionnaire request.form sera :
{'nom':'HOPPER', 'prenom':'Grace'}
Le template resultat.html utilise des paramètres nom et prenom.
En réponse à la requête POST, le serveur renvoie une page HTML créée à partir du template resultat.html et des paramètres nom et prenom. Si l'utilisateur a saisi HOPPER et Grace, le navigateur affichera :
Bonjour Grace HOPPER, j'espère que vous allez bien.
Pour gérer le formulaire, il est possible d'utiliser une méthode HTTP GET à la place de la méthode POST :
A faire vous même :
Remixer votre précédent projet et renommer le avec votre prénom au format
prenom-1nsi-ecmorlaix-flask-ex2-get.Modifier le fichier
index.htmlavec votre prénom tel que :
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Le formulaire</title>
</head>
<body>
<form action="https://prenom-1nsi-ecmorlaix-flask-ex2-get.glitch.me/resultat" method="get">
<label>Nom</label> : <input type="text" name="nom" />
<label>Prénom</label> : <input type="text" name="prenom" />
<input type="submit" value="Envoyer" />
</form>
</body>
</html>
- Modifier le fichier
serveur.pytel que :
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/resultat',methods = ['GET'])
def resultat():
result = request.args
n = result['nom']
p = result['prenom']
return render_template("resultat.html", nom=n, prenom=p)
app.run()
Dans index.html, la méthode POST a été remplacée par la méthode GET. Dans le fichier serveur.py nous avons aussi remplacé POST par GET, et on utilise request.args à la place de request.form.
- Tester en cliquant sur le bouton
Showle fonctionnement de votre serveur Web, vérifier les requètes dansLogs, puis copier/coller un lien vers votre projet dans le code Python de la cellule suivante pour l'intégrer dans ce notebook :
%%HTML
<center>
<iframe src="..." width=70% height="500" ></iframe>
</center>
- Saisir
Gracepour le prénom etHOPPERpour le nom puis valider en cliquant sur le boutonEnvoyer. Observer alors attentivement la barre d'adresse du navigateur. Que remarquez-vous de particulier ?
...
Vous avez dû remarquer que cette fois-ci, les informations du formulaire sont transmises au serveur par l'intermédiaire de l'URL : https://prenom-1nsi-ecmorlaix-flask-ex2-get.glitch.me/resultat?nom=HOPPER&prenom=Grace
Dans le cas de l'utilisation d'une méthode POST les données issues d'un formulaire sont envoyées au serveur sans être directement visibles, alors que dans le cas de l'utilisation d'une méthode GET, les données sont visibles (et accessibles) puisqu'elles sont envoyées par l'intermédiaire de l'URL. De plus, les données envoyées par l'intermédiaire d'une méthode "GET" peuvent être modifiées directement dans l'URL...
- Selon vous, laquelle de ces méthodes est à préférer dans le cas d'une transmission de données du client au serveur avec les formulaires ?
...
Références aux programmes :¶
| Contenus | Capacités attendues | Commentaires |
|---|---|---|
| Interaction clientserveur. Requêtes HTTP, réponses du serveur |
Distinguer ce qui est exécuté sur le client ou sur le serveur et dans quel ordre. Distinguer ce qui est mémorisé dans le client et retransmis au serveur. Reconnaître quand et pourquoi la transmission est chiffrée. |
Il s’agit de faire le lien avec ce qui a été vu en classe de seconde et d’expliquer comment on peut passer des paramètres à un site grâce au protocole HTTP. |
| Formulaire d’une page Web | Analyser le fonctionnement d’un formulaire simple. Distinguer les transmissions de paramètres par les requêtes POST ou GET. |
Discuter les deux types de requêtes selon le type des valeurs à transmettre et/ou leur confidentialité. |

Ce document, basé sur le travail de David ROCHE, est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International.
Pour toute question, suggestion ou commentaire : eric.madec@ecmorlaix.fr