OUJOOD.COM
Introduction : Formulaires et traitement des données avec Express.js
Dans cet article, nous allons apprendre à créer un formulaire HTML, récupérer les données envoyées en POST et répondre dynamiquement avec Express.js. C’est un pas important pour rendre nos applications interactives : l’utilisateur saisit son nom et notre serveur lui répond « Bonjour, [nom] ! ».
Étape 1 : Préparer votre environnement
Avant de coder, assurez-vous d’avoir Node.js installé. Ensuite :
- Installez Node.js : téléchargez-le depuis nodejs.org et vérifiez avec
node -v. - Créez un dossier de projet : par exemple
formulaire-express, puis ouvrez-le dans votre éditeur. - Initialisez npm : dans le terminal, tapez
npm init -y. - Installez Express : exécutez
npm install express.
Étape 2 : Créer et afficher un formulaire (GET /)
Nous allons écrire un premier serveur qui affiche une page avec un formulaire HTML.
// index.js — serveur minimal + formulaire
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.send(` <!doctype html>
<html lang="fr">
<head><meta charset="utf-8"><title>Formulaire</title></head>
<body>
<h1>Entrez votre nom</h1>
<form method="POST" action="/submit">
<label>Nom : </label>
<input type="text" name="nom" required>
<button type="submit">Envoyer</button>
</form>
</body>
</html>
`);
});
app.listen(3000, function() {
console.log("Serveur démarré sur [http://localhost:3000](http://localhost:3000)");
});
Explication du code Express.js
C'est un exemple de base parfait pour débuter avec Express et les formulaires HTML.
Ce code crée un serveur web minimal avec Express.js qui affiche un formulaire simple :
Fonctionnalités principales :
Serveur Express
Utilise le framework Express.js pour créer un serveur web léger
Route principale (GET /)
- Affiche une page HTML avec un formulaire
- Le formulaire contient un champ "Nom" obligatoire
- Bouton "Envoyer" pour soumettre les données
Structure du formulaire
- Méthode POST vers la route
/submit - Input de type texte avec l'attribut
required - Interface en français avec titre et labels appropriés
Démarrage du serveur
Écoute sur le port 3000 avec message de confirmation
Limitation importante :
Le code ne gère pas la route POST /submit — quand l'utilisateur soumet le formulaire, cela provoquera une erreur 404 car cette route n'existe pas encore.
Pour fonctionner complètement, il faudrait ajouter une route comme :
app.post('/submit', function(req, res) {
// Traitement des données du formulaire
});
Et c'est ce que nous allons voir dans la suite.
Étape 3 : Lire les données envoyées (express.urlencoded)
Pour traiter les données du formulaire, nous devons ajouter un middleware. Depuis Express 4.16+, on peut utiliser express.urlencoded() sans installer de package externe.
// index.js — lire les données de formulaire avec express.urlencoded
var express = require('express');
var app = express();
app.use(express.urlencoded({ extended: false })); // Middleware intégré
app.get('/', function(req, res) {
res.send(` <!doctype html>
<html lang="fr">
<head><meta charset="utf-8"><title>Formulaire</title></head>
<body>
<h1>Entrez votre nom</h1>
<form method="POST" action="/submit">
<label>Nom : </label>
<input type="text" name="nom" required>
<button type="submit">Envoyer</button>
</form>
</body>
</html>
`);
});
app.post('/submit', function(req, res) {
var nom = req.body.nom;
res.send(`<h1>Bonjour, ${nom || "inconnu"} !</h1>`);
});
app.listen(3000, () => console.log("[http://localhost:3000](http://localhost:3000)"));
Explication du code Express.js avec traitement de formulaire
Ce code crée un serveur web complet avec Express.js qui affiche un formulaire et traite ses données :
Fonctionnalités principales :
Middleware pour formulaires
app.use(express.urlencoded({ extended: false })) permet de parser automatiquement les données de formulaires HTML et les rendre disponibles dans req.body
Route principale (GET /)
- Affiche une page HTML avec un formulaire
- Le formulaire contient un champ "Nom" obligatoire
- Bouton "Envoyer" pour soumettre les données
Route de traitement (POST /submit)
- Récupère la valeur du champ "nom" via
req.body.nom - Affiche un message de salutation personnalisé
- Gère le cas où le nom est vide avec "inconnu" comme fallback
Démarrage du serveur
Écoute sur le port 3000 avec URL directe affichée en console
Avantages de cette version :
- Fonctionnel complet : Le formulaire fonctionne de bout en bout
- Gestion des données : Les informations saisies sont correctement traitées
- Sécurité basique : Gestion du cas où le nom n'est pas fourni
- Interface simple : Retour immédiat à l'utilisateur
C'est un exemple parfait d'application web basique avec formulaire fonctionnel.
Étape 4 : Variante avec body-parser
Avant que express.urlencoded soit intégré, on utilisait le module externe body-parser. Voici la variante :
// index.js — variante avec body-parser
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', function(req, res) {
// même formulaire que plus haut
});
app.post('/submit', function(req, res) {
var nom = req.body.nom;
res.send(`<h1>Bonjour, ${nom} !</h1>`);
});
Explication du code Express.js avec body-parser (version alternative)
Ce code montre une variante alternative du serveur précédent utilisant le module externe body-parser :
Différences principales :
Middleware externe
bodyParser.urlencoded({ extended: false }) remplace express.urlencoded() — même fonctionnalité mais via un module séparé
Installation requise
Nécessite d'installer le package body-parser séparément :
npm install body-parser
Fonctionnalités identiques
- Route GET / avec formulaire (code commenté mais identique)
- Route POST /submit qui traite les données
- Récupération du nom via
req.body.nom - Affichage du message de salutation
Contexte historique :
- Ancienne méthode :
body-parserétait un module externe obligatoire - Méthode moderne :
express.urlencoded()est intégré directement dans Express 4.16+ - Compatibilité : Les deux approches fonctionnent de manière identique
Recommandation : Utiliser la version moderne avec express.urlencoded() pour éviter une dépendance externe.
Étape 5 : Contrôler les données et gérer les erreurs
Il est important de vérifier ce que l’utilisateur envoie. Voici une version sécurisée qui renvoie une erreur si le champ est vide et échappe la valeur côté succès (micro-amélioration n°1) :
// index.js — contrôle minimal + échappement anti-XSS
function escapeHtml(str) {
return String(str)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
app.post('/submit', function(req, res) {
var nom = (req.body.nom || "").trim();
if (!nom) {
return res.status(400).send(` <h1>Le nom est requis.</h1>
<p><a href="/">Revenir au formulaire</a></p>
`);
}
const nomSafe = escapeHtml(nom);
res.send(`<h1>Bonjour, ${nomSafe}!</h1>`);
});
Bonus : Utiliser EJS pour séparer les vues
Pour un code plus propre, on peut utiliser EJS. Cela permet de mettre le HTML dans des fichiers de vues distincts.
// index.js — Express + EJS + express.urlencoded() (avec valeur persistante)
// Micro-améliorations n°2 & n°3 : conserver la saisie et autofocus dans la vue
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
app.use(express.urlencoded({ extended: false }));
app.get('/', function(req, res) {
res.render('form', { erreur: null, nom: "" });
});
app.post('/submit', function(req, res) {
var nom = (req.body.nom || "").trim();
if (!nom) {
return res.status(400).render('form', { erreur: "Le nom est requis.", nom });
}
res.render('result', { nom: nom });
});
app.listen(3000, () => console.log("[http://localhost:3000](http://localhost:3000)"));
<!-- views/form.ejs -->
<!doctype html>
<html lang="fr">
<head><meta charset="utf-8"><title>Formulaire</title></head>
<body>
<h1>Entrez votre nom</h1>
<% if (erreur) { %>
\<p style="color\:red"><%= erreur %>\</p>
<% } %>
\<form method="POST" action="/submit">
\<label>Nom : \</label>
\<input
type="text"
name="nom"
value="<%= typeof nom !== 'undefined' ? nom : '' %>"
required
autofocus
\>
\<button type="submit">Envoyer\</button>
\</form>
\</body>
\</html>
<!-- views/result.ejs --> <!doctype html> <html lang="fr"> <head><meta charset="utf-8"><title>Résultat</title></head> <body> <h1>Bonjour, <%= nom %> !</h1> <p><a href="/">Revenir au formulaire</a></p> </body> </html>
Explication du code Express.js avec EJS (moteur de templates)
Ce code montre une architecture améliorée utilisant EJS pour séparer la logique métier de la présentation :
Configuration EJS :
Moteur de templates
app.set('view engine', 'ejs');
- Configure EJS comme moteur de rendu par défaut
- Permet d'utiliser
res.render()au lieu deres.send() - Cherche automatiquement les fichiers dans le dossier
views/
Structure de l'application :
Fichier principal (index.js)
- Route GET / : Affiche le formulaire avec
res.render('form', { erreur: null, nom: "" }) - Route POST /submit : Valide et traite les données
- Gestion d'erreur : Ré-affiche le formulaire avec message d'erreur et saisie conservée
- Succès : Affiche la page de résultat avec le nom
Vue formulaire (views/form.ejs)
- Affichage conditionnel :
<% if (erreur) { %>pour les messages d'erreur - Échappement sécurisé :
<%= erreur %>évite les attaques XSS - Valeur persistante : l’input est pré-rempli avec la dernière saisie
- Confort :
autofocussur le champ
Vue résultat (views/result.ejs)
- Affichage du nom :
<%= nom %>avec échappement automatique - Navigation : Lien de retour vers le formulaire
- Page dédiée : Interface claire pour le succès
Installation requise :
npm install ejs
C'est un excellent exemple d'architecture web moderne avec séparation propre entre la logique et la présentation.
Conclusion
Dans ce tutoriel, vous avez appris à :
- Créer un formulaire HTML avec Express.
- Lire les données envoyées en POST avec
express.urlencodedoubody-parser. - Ajouter une validation minimale côté serveur (avec échappement anti-XSS).
- Utiliser EJS pour séparer les vues, conserver la saisie en cas d’erreur et améliorer l’UX.
Dans le prochain cours, nous irons plus loin avec la validation (emails, messages clairs) et nous préparerons la connexion avec une base de données.