Recevoir un formulaire par e-mail

Recevoir un formulaire par e-mail6 min de lecture

Envoyer un formulaire HTML par e-mail sans PHP

Remplacez un script contact.php qui appelle mail() par un formulaire qui envoie vers un endpoint hébergé, en gardant vos noms de champs, votre page de remerciement et les réponses.

Preet SutharFondateur, Ikiform

Remplacez l'action du formulaire, qui pointe vers votre script PHP, par l'URL d'un backend de formulaires, gardez les noms de champs et supprimez le script. Le backend fait ce que faisait mail(), plus ce qu'il n'a jamais bien fait : filtrer le spam, stocker et envoyer des e-mails qui n'atterrissent pas dans les spams. Cela fonctionne sur les hébergeurs statiques où PHP ne peut pas tourner du tout.

Ce qui change ici

La plupart des formulaires de contact PHP sont les mêmes vingt lignes, copiées d'un tutoriel il y a des années. Ils lisent $_POST, construisent une chaîne, appellent mail() et redirigent. En voici un typique :

contact.php
<?php
$name = $_POST["name"];
$email = $_POST["email"];
$phone = $_POST["phone"];
$message = $_POST["message"];

$to = "hello@example.com";
$subject = "Website enquiry from $name";
$body = "Name: $name\nEmail: $email\nPhone: $phone\n\n$message";
$headers = "From: $email\r\nReply-To: $email";

if (mail($to, $subject, $body, $headers)) {
  header("Location: /thanks.html");
} else {
  echo "Sorry, something went wrong.";
}

Il a l'air inoffensif, et il fonctionnait quand il a été écrit. Aujourd'hui, il casse de quatre façons, et seule la première est visible :

ProblèmePourquoi cela arrive
Pas de PHP chez l'hébergeurGitHub Pages, Netlify, Vercel, Cloudflare Pages et S3 servent des fichiers ; ils n'exécutent pas PHP. Le formulaire envoie vers un fichier qui n'est jamais exécuté, et vous obtenez un 404 ou un 405.
Les e-mails finissent en spam, ou disparaissentmail() confie le message au programme de messagerie local du serveur. L'en-tête From: prétend venir de l'adresse du visiteur, mais l'e-mail part du serveur de votre hébergeur : il échoue donc aux vérifications SPF et DMARC du domaine du visiteur. Gmail et Outlook le filtrent ou le rejettent, souvent sans rien dire.
Injection d'en-têtes$email va dans les en-têtes sans vérification. Un bot qui envoie une valeur contenant un saut de ligne peut ajouter sa propre ligne Bcc: et utiliser votre formulaire pour envoyer du spam, ce qui fait mettre l'IP de votre hébergeur sur liste noire.
Rien n'est conservéSi l'e-mail se perd, le message aussi. Il n'y a ni trace, ni filtre anti-spam, ni moyen de retrouver les demandes du mois dernier.

Vous pourriez corriger chaque point : valider chaque valeur, envoyer via un fournisseur SMTP avec une bibliothèque comme PHPMailer, configurer SPF et DKIM pour votre domaine, ajouter un honeypot et une limite de débit, et tout journaliser dans une base de données. C'est un projet raisonnable si vous faites déjà tourner du PHP. Sinon, confiez ce travail à un backend de formulaires.

Le même formulaire avec mail() de PHP et avec un backend de formulairesavec contact.phpavec un backend de formulairesvotreformulaireaction="/contact.php"mail()From : le visiteur,envoyé parl'hébergeurdossier spaméchoue à SPF etDMARCvotreformulairemêmes champs,nouvelle actionIkiformfiltre le spam,stockevotre boîteReply-To : levisiteurenvoimail localenvoie-mailLe même formulaire avec mail() de PHP et avec un backend de formulairesavec contact.phpavec un backend de formulairesvotre formulaireaction="/contact.php"mail()From : le visiteur, envoyé parl'hébergeurdossier spaméchoue à SPF et DMARCvotre formulairemêmes champs, nouvelle actionIkiformfiltre le spam, stockevotre boîteReply-To : le visiteurenvoimail localenvoie-mail
  1. Avec contact.php, le formulaire envoie vers votre hébergeur, et mail() envoie un message qui prétend venir du visiteur. Les serveurs destinataires voient un expéditeur qui ne correspond pas au domaine et le classent en spam ou le suppriment.
  2. Avec un backend de formulaires, le formulaire envoie les mêmes champs à Ikiform. Ikiform envoie l'e-mail depuis son propre domaine et met l'adresse du visiteur dans Reply-To, ce qui est précisément le rôle de Reply-To.
La solution à la délivrabilité n'est pas un meilleur script. C'est d'envoyer depuis un domaine autorisé à envoyer.

Sortir le formulaire de PHP

Gardez les noms de champs exactement tels quels. Seule l'action change, plus deux inputs masqués :

Avant
<form action="/contact.php" method="post">
  <input name="name" required />
  <input name="email" type="email" required />
  <input name="phone" type="tel" />
  <textarea name="message" required></textarea>
  <button>Send</button>
</form>
Après
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <input name="name" required />
  <input name="email" type="email" required />
  <input name="phone" type="tel" />
  <textarea name="message" required></textarea>
  <input type="hidden" name="_redirect" value="https://example.com/thanks.html" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send</button>
</form>

Puis faites correspondre chaque chose que faisait le script à l'endroit où elle se trouve désormais :

Dans contact.phpDésormais
$to = "hello@example.com"Les destinataires, dans les réglages Notifications du formulaire
header("Location: /thanks.html")L'input masqué _redirect, ou Redirect after submit dans les réglages du formulaire
Reply-To: $emailAutomatique, car le champ s'appelle email
$subject = "Website enquiry from $name"Fixé à New submission: <form name>. Nommez le formulaire « Demande depuis le site » pour garder la formulation
echo "Sorry, something went wrong."La page d'erreur d'Ikiform pour un envoi classique, ou votre propre message avec fetch
Les vérifications que vous n'avez jamais écritesLe honeypot _gotcha, le score de spam, les limites de débit et la validation des champs
  • Ajoutez votre domaine dans Allowed domains. _redirect ne fonctionne que pour une URL https: sur l'un de ces domaines.
  • Supprimez contact.php du serveur une fois le nouveau formulaire en place. Un script oublié reste un relais mail ouvert pour les bots qui se souviennent de l'URL.
  • Si vous êtes passé à un hébergeur statique, l'ancienne URL /contact.php n'existe plus. Les bots qui envoient directement dessus reçoivent un 404, et c'est très bien.
Si votre formulaire était une extension WordPress plutôt qu'un script, le principe est le même. Le guide WordPress montre où placer le formulaire dans un thème à blocs.

Vérifiez que tout fonctionne

  1. Dans Allowed domains du formulaire, ajoutez le domaine de votre site, plus localhost pendant le développement. Laissez vide pour accepter les envois de partout.
  2. Envoyez le formulaire sur votre page en ligne. Vous arrivez sur votre ancienne thanks.html.
  3. Ouvrez Submissions dans le tableau de bord. La nouvelle soumission y est, avec tous les champs envoyés.
  4. Ouvrez l'e-mail. Il vient d'Ikiform, pas de l'adresse du visiteur, et n'est pas dans les spams. Ajoutez l'expéditeur à vos contacts pour que les suivants n'y soient pas non plus.
  5. Cliquez sur Reply. L'adresse du visiteur est sur la ligne To.
  6. Envoyez avec le honeypot rempli, _gotcha=bot. L'envoi reçoit quand même une réponse de succès, mais la soumission est stockée comme spam et n'envoie ni e-mail ni webhook.

Pièges

  • Anciens noms de formulaire avec crochets. Les formulaires PHP utilisent souvent des noms comme contact[email]. Ikiform les stocke tels quels, mais l'adresse de réponse ne vient que d'un champ nommé email ou de quelques variantes proches. Renommez le champ, ou ajoutez _replyto.
  • L'objet ne peut pas inclure le nom. L'objet du script contenait le nom du visiteur. L'objet de la notification est fixe, et _subject est transmis aux webhooks et à l'API sans changer l'e-mail.
  • Encodage des caractères. Les scripts mail() abîmaient souvent les accents parce qu'ils ne définissaient jamais de charset. L'e-mail d'Ikiform est en UTF-8, les noms dans n'importe quelle écriture arrivent donc intacts.
  • Plusieurs adresses dans $to. Une liste séparée par des virgules dans le script devient des destinataires distincts dans le tableau de bord. Les adresses extérieures confirment par lien avant de recevoir quoi que ce soit. Voir plusieurs destinataires.

Si quelque chose ne va pas

ProblèmeQue faire
Le navigateur arrive sur la page de remerciement d'Ikiform au lieu de la vôtre_redirect est ignoré sauf si son domaine figure dans Allowed domains et qu'il s'agit d'une URL https:. Ajoutez le domaine, ou définissez plutôt Redirect after submit dans les réglages du formulaire.
403 origin_not_allowed, ou tous les envois finissent en spamLe domaine de la page n'est pas dans les Allowed domains du formulaire. Ajoutez-le, plus localhost pour les tests en local. Les sous-domaines d'un domaine listé sont autorisés.
Le formulaire envoie toujours vers le fichier PHPUne page en cache ou une seconde copie du formulaire, comme un include de pied de page, a encore l'ancienne action. Cherchez contact.php dans tout le site.
La soumission est dans le tableau de bord mais aucun e-mail ni webhook n'est arrivéElle a été stockée comme spam. Le spam n'envoie rien. Ouvrez-la sous le filtre Spam pour voir les raisons, et marquez-la comme non-spam pour envoyer son e-mail et ses webhooks.

Questions

Une étape vous bloque, ou vous voulez un guide pour votre cas ? Écrivez à hello@ikiform.com.