Correction contact: alerte form marche en file:// pas localhost (preventDefault manquant + form qui poste, 501 du serveur) + explication file:// vs http://localhost
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# 🔧 Pourquoi l'alerte « marche » en `file://` mais pas en `localhost`
|
||||
|
||||
Excellente observation 👀 — et ce n'est pas un hasard. La réponse t'apprend une vraie notion.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 La cause : ton formulaire **s'envoie vraiment**
|
||||
|
||||
Regarde le `else` de ton `submit` :
|
||||
|
||||
```js
|
||||
formulaire.addEventListener("submit", function (evenement) {
|
||||
if (zoneMessage.value.trim() === "") {
|
||||
evenement.preventDefault(); // ✅ ici tu annules l'envoi
|
||||
alert("Merci d'écrire un message avant d'envoyer !");
|
||||
} else {
|
||||
const greeting = `merci ${nom.value}, ...`;
|
||||
alert(`${greeting}`); // ❌ mais ici, PAS de preventDefault
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Dans le cas « message rempli » (le `else`), tu affiches l'alerte… mais tu **n'appelles pas** `evenement.preventDefault()`. Donc, après l'alerte, le navigateur fait ce qu'un `<form>` fait par défaut : il **envoie le formulaire** (ton form est en `method="post" action=""`, donc il poste vers la page elle-même).
|
||||
|
||||
Et c'est cet envoi qui se comporte différemment selon comment tu ouvres la page 👇
|
||||
|
||||
---
|
||||
|
||||
## 🆚 Pourquoi la différence `file://` vs `localhost`
|
||||
|
||||
| | Double-clic (`file://`) | Serveur (`http://localhost:...`) |
|
||||
|---|---|---|
|
||||
| Y a-t-il un serveur pour recevoir le POST ? | **Non** | **Oui** (celui que tu as lancé) |
|
||||
| Que devient l'envoi du formulaire ? | bloqué / ne mène nulle part | le serveur **reçoit** le POST et **répond** |
|
||||
| Ce que tu vois après l'alerte | rien ne bouge → « ça marche » | la page part sur une **page d'erreur** → « ça ne marche pas » |
|
||||
|
||||
- En **`file://`**, il n'y a **aucun serveur**. Un `<form>` ne peut pas « poster » vers un simple fichier → l'envoi est ignoré. Du coup, après ton alerte, **rien ne se passe** : tout a l'air normal.
|
||||
- En **`http://localhost`**, il y a un **vrai serveur** (celui que tu as démarré). Il **reçoit** ton POST… mais le petit serveur de dev ne sait pas traiter un POST → il renvoie une erreur (souvent **501 « Unsupported method »**), et le navigateur **t'emmène sur cette page d'erreur**, juste après l'alerte. D'où l'impression que « l'alerte ne marche pas ».
|
||||
|
||||
> 🔎 En réalité, ton alerte **s'affiche dans les deux cas** ! La différence, c'est ce qui se passe **juste après** : sur localhost, la page s'en va sur l'erreur du serveur, donc tu ne profites pas du résultat.
|
||||
|
||||
---
|
||||
|
||||
## ✅ La correction
|
||||
|
||||
Comme tu n'as **pas de vrai serveur** pour traiter l'envoi (et ce n'est pas le but ici), tu dois **empêcher l'envoi par défaut dans tous les cas**, pas seulement quand le message est vide.
|
||||
|
||||
Deux façons :
|
||||
- soit ajouter `evenement.preventDefault();` **aussi** dans le `else`,
|
||||
- soit (plus propre) l'appeler **une seule fois, tout en haut** du gestionnaire, avant le `if`. Comme ça, l'envoi est toujours annulé, et c'est ton JavaScript qui décide quoi faire (afficher l'alerte).
|
||||
|
||||
**✅ Test :** après correction, tu remplis le message, tu cliques « Envoyer » → l'alerte s'affiche **et la page ne bouge plus**, que tu sois en `file://` ou en `localhost`. Comportement identique partout.
|
||||
|
||||
> 💡 **À retenir :** tant qu'il n'y a pas de serveur qui gère vraiment l'envoi, on met **`preventDefault()`** pour garder la main et tout faire en JS. Se reposer sur « de toute façon en `file://` ça ne part pas » est trompeur : dès qu'un serveur est là (localhost, et plus tard en ligne), le comportement change.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Bonus — bien comprendre `file://` vs `http://localhost`
|
||||
|
||||
C'est **deux façons différentes** d'ouvrir la même page. Regarde ta **barre d'adresse**, elle te dit dans quel mode tu es.
|
||||
|
||||
- **`file:///.../contact.html`** → **aucun serveur**. Le navigateur **lit le fichier directement sur ton disque**, comme une photo ou un PDF. Pas d'adresse web, pas d'« origine ». C'est pour ça que `fetch` y est bloqué (« CORS policy ») et qu'un `<form>` n'a personne à qui poster.
|
||||
- **`http://localhost:8000/...`** → tu as lancé un **petit serveur** qui **publie** ton dossier et **répond aux demandes**, comme un vrai site, mais sur ta machine. Là il y a une vraie adresse → `fetch` fonctionne, et un POST de formulaire est bel et bien reçu (d'où l'erreur 501 plus haut, faute de code pour le traiter).
|
||||
|
||||
Décodage de l'adresse : **`localhost`** = ta propre machine ; **`8000`** (ou `5500`, `3000`…) = le **port**, le « numéro de porte » où ton serveur écoute.
|
||||
|
||||
> 🧭 L'image à garder : `file://` = lire un papier posé sur ton bureau. `http://localhost:...` = un mini-site web monté chez toi, que tu visites comme n'importe quel site. Les vraies fonctionnalités du web (`fetch`, et le traitement d'un `<form>`) ont besoin de la **deuxième** situation — ce qui explique pourquoi ton comportement change d'un mode à l'autre.
|
||||
Reference in New Issue
Block a user