Premier formulaire POST¶
Objectif : envoyer une valeur depuis un formulaire HTML et la lire côté contrôleur.
Ce que vous allez apprendre : afficher un formulaire HTML protégé
par un jeton CSRF, le soumettre en POST, et lire la valeur reçue dans
le corps de la requête avec request.form("name", ...) (et non dans
l'URL).
Palier 8 de la progression officielle des starters, après Le jeton CSRF.
Prérequis : comprendre le jeton CSRF (palier 7).
Ce que ce starter montre¶
- une route
GET /form-post - une route
POST /form-post - une vue HTML avec un formulaire minimal
- une méthode de contrôleur qui lit la valeur envoyée
- une réponse texte avec
Response.text(...)
Aucune base de données. Aucune validation serveur avancée. Aucun CRUD.
Classes Forge utilisées¶
| Classe | Rôle dans ce starter | Référence |
|---|---|---|
Request |
Lire les champs envoyés avec request.form(...). |
Request |
Response |
Construire la réponse texte avec Response.text(...). |
Response |
BaseController |
Fournit render(...) pour la vue et csrf_token(...) pour le jeton CSRF. |
BaseController |
Tester¶
Depuis le projet Forge déjà créé avec ce starter :
Ouvrez :
Saisissez Roger, envoyez le formulaire.
Résultat attendu :
Les routes¶
# mvc/routes.py
from mvc.controllers.form_post_controller import FormPostController
with router.group("", public=True) as pub:
pub.add("GET", "/form-post", FormPostController.index, name="form_post_index")
pub.add("POST", "/form-post", FormPostController.submit, name="form_post_submit")
Le contrôleur¶
# mvc/controllers/form_post_controller.py
from core.http.request import Request
from core.http.response import Response
from core.mvc.controller.base_controller import BaseController
class FormPostController(BaseController):
@staticmethod
def index(request: Request) -> Response:
return BaseController.render(
"form_post/index.html",
request=request,
context={"csrf_token": BaseController.csrf_token(request)},
)
@staticmethod
def submit(request: Request) -> Response:
name = request.form("name", default="Forge")
return Response.text(f"Bonjour {name}")
Comprendre ce code¶
- Deux méthodes pour un même chemin
/form-post, mais des verbes HTTP différents :GETaffiche le formulaire,POSTreçoit la soumission. BaseController.csrf_token(request)génère le jeton CSRF à injecter dans la vue. Sans ce jeton, Forge refuse lePOST(protection contre les soumissions cross-site).- Côté
submit,request.form("name", default="Forge")lit la valeur envoyée dans le corps du formulaire — pas dans l'URL. - Une fois la donnée traitée, le contrôleur retourne une réponse. Ici un
simple
Response.text(...); dans une vraie application on redirigerait généralement vers une page de confirmation.
La vue¶
<!-- mvc/views/form_post/index.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Premier formulaire POST — Forge</title>
</head>
<body>
<h1>Premier formulaire POST</h1>
<form method="post" action="/form-post">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<label for="name">Prénom</label>
<input id="name" name="name" type="text" value="Forge">
<button type="submit">Envoyer</button>
</form>
</body>
</html>
Comprendre ce code¶
method="post"indique au navigateur d'envoyer les données dans le corps de la requête, pas dans l'URL.- Le champ caché
csrf_tokentransporte le jeton généré par le contrôleur. Le middleware CSRF de Forge vérifie sa correspondance avant d'appelersubmit. name="name"est la clé lue côté serveur parrequest.form("name").
À retenir¶
GET /form-postaffiche le formulaire.POST /form-postreçoit les données.- Le contrôleur lit la valeur envoyée avec
request.form("name", ...). - Le champ caché
csrf_tokenest exigé par Forge sur toute requête POST (protection contre les soumissions cross-site). Il est généré parBaseController.csrf_token(request)et vérifié automatiquement par le middleware. - La validation serveur complète viendra au palier suivant (palier 9).
Après ce starter¶
Passez au palier suivant : Validation serveur.
Vous y apprendrez à refuser une valeur vide avec un statut HTTP explicite :