Formulaire de contact sur un site statique6 min de lecture
Ajouter un formulaire de contact à un site statique Amazon S3
Les website endpoints S3 n'acceptent que GET et HEAD en HTTP simple : envoyez le formulaire à un backend et gérez bien les redirections avec CloudFront.
Un website endpoint S3 répond à un POST de formulaire par 405 MethodNotAllowed : faites donc pointer l'action du formulaire vers votre endpoint Ikiform. Comme l'endpoint est en http: simple, un _redirect vers lui n'est jamais suivi ; définissez Redirect after submit dans les réglages du formulaire, ou placez CloudFront devant pour avoir du https:. Avec CloudFront devant le REST endpoint du bucket, redirigez vers un nom de fichier complet comme thanks.html, car l'objet racine par défaut ne s'applique qu'à la racine.
Ce qui change sur S3
Un bucket configuré pour l'hébergement de site statique a son propre website endpoint, comme http://www.example.com.s3-website-us-east-1.amazonaws.com. AWS indique qu'il ne prend en charge que les requêtes GET et HEAD sur les objets. Un envoi de formulaire reçoit une page d'erreur HTML :
<html>
<head><title>405 Method Not Allowed</title></head>
<body>
<h1>405 Method Not Allowed</h1>
<ul>
<li>Code: MethodNotAllowed</li>
<li>Message: The specified method is not allowed against this resource.</li>
<li>Method: POST</li>
<li>ResourceType: OBJECT</li>Trois autres particularités de S3 façonnent le formulaire de contact :
| Particularité de S3 | Conséquence pour le formulaire |
|---|---|
| Les website endpoints ne prennent pas en charge HTTPS | Ikiform ne suit un _redirect que vers une URL https: : une redirection vers l'endpoint nu est donc ignorée |
| Les en-têtes de réponse viennent de CloudFront, pas du bucket | Une Content-Security-Policy se définit dans une politique d'en-têtes de réponse CloudFront |
| L'objet racine par défaut de CloudFront ne s'applique qu'à la racine | Avec une origine REST, https://example.com/thanks/ ne charge pas thanks/index.html ; redirigez vers thanks.html |
Pour un site en https:, AWS recommande Amplify Hosting, qui repose sur CloudFront, ou CloudFront devant le bucket. Le formulaire fonctionne dans les deux cas. Ce qui change, c'est l'endroit où arrive le visiteur après l'envoi.
- Sur le website endpoint nu, la page est servie en http et envoie à Ikiform.
- Ikiform stocke le message, mais ignore un _redirect vers une adresse http et affiche sa page de remerciement hébergée.
- Définir Redirect after submit dans le tableau de bord contourne ce problème, car ce réglage accepte les URL http.
- Derrière CloudFront avec votre propre domaine, la page est en https.
- Ikiform suit le _redirect vers votre thanks.html, tant que le domaine figure dans Allowed domains.
Quelle origine CloudFront
CloudFront peut lire le bucket de deux façons, et ce choix détermine la forme de votre URL de remerciement :
| Origine | Bucket | Pages d'index de dossier | URL de remerciement |
|---|---|---|---|
| Le website endpoint S3, comme origine personnalisée | Doit être lisible publiquement | Fonctionnent : /thanks/ charge thanks/index.html | /thanks/ ou /thanks.html |
| Le REST endpoint, avec origin access control | Reste privé, lu uniquement par CloudFront | Seulement la racine, via l'objet racine par défaut | /thanks.html, un nom de fichier complet |
Un nom de fichier complet fonctionne dans les deux cas, c'est pourquoi les exemples en utilisent un. Si vous préférez ne pas gérer CloudFront vous-même, Amplify Hosting peut déployer depuis le bucket avec https: et un CDN géré ; le formulaire n'y demande aucune modification non plus.
Le formulaire
Les sites S3 sont souvent des sites d'entreprise : ce formulaire demande donc un e-mail professionnel et le nom de l'entreprise. Téléversez-le sous le nom contact.html à côté de thanks.html :
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required />
<label for="email">Work email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="company">Company</label>
<input id="company" name="company" autocomplete="organization" />
<label for="message">How can we help?</label>
<textarea id="message" name="message" rows="6" minlength="10" required></textarea>
<input type="hidden" name="_redirect" value="https://www.example.com/thanks.html" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button type="submit">Send</button>
</form>- Le
_redirectpointe vers le domaine CloudFront, avec un nom de fichier. Il n'est suivi que siwww.example.comouexample.comfigure dans Allowed domains. - Sur l'endpoint
http:nu, retirez l'input_redirectet réglez plutôt Redirect after submit sur la page de remerciement. Ce réglage accepte les URLhttp:, car seule votre équipe peut le modifier. - Gardez
emailcomme nom de champ. Les e-mails de notification l'utilisent comme adresse de réponse.
Sur un site d'entreprise, plusieurs personnes lisent généralement la boîte de contact. Ajoutez jusqu'à 10 destinataires de notification confirmés au formulaire ; chacun reçoit le message, et celui qui clique sur Reply répond directement à l'expéditeur. Si les messages doivent aussi arriver dans un canal partagé ou une file de tickets, ajoutez un webhook signé et acheminez-le via Zapier ou votre propre code. Le champ company arrive en texte brut, prêt à être filtré dans l'un ou l'autre.
Avant de téléverser, testez la page depuis un serveur local avec localhost dans Allowed domains. Les envois depuis localhost comptent comme des tests : vous pouvez donc mettre le formulaire au point avant même que le bucket ne le serve.
Synchronisez le dossier avec le bucket, et invalidez les pages dans CloudFront pour que le nouveau formulaire soit servi tout de suite :
aws s3 sync ./site s3://www.example.com --delete
aws cloudfront create-invalidation --distribution-id E1EXAMPLE --paths "/contact.html" "/thanks.html"Domaines autorisés sur les hôtes AWS
| Où la page est servie | À ajouter |
|---|---|
| Website endpoint nu | L'hôte complet de l'endpoint du bucket, comme www.example.com.s3-website-us-east-1.amazonaws.com |
| Domaine CloudFront par défaut | L'hôte exact d111111abcdef8.cloudfront.net, pendant vos tests |
| Votre propre domaine | example.com, qui couvre aussi www.example.com |
N'ajoutez jamais seuls amazonaws.com, un suffixe régional s3-website ou cloudfront.net. Tous les buckets ou distributions du monde correspondraient. AWS inscrit les domaines des website endpoints S3 dans la Public Suffix List pour la même raison : chaque bucket est un site distinct.
Les en-têtes via CloudFront
Les métadonnées d'objet S3 ne peuvent pas définir de Content-Security-Policy : définissez-la dans une politique d'en-têtes de réponse CloudFront et associez-la au comportement de cache par défaut de la distribution. La valeur de l'en-tête est limitée à 1 783 caractères :
{
"Name": "site-csp",
"SecurityHeadersConfig": {
"ContentSecurityPolicy": {
"Override": true,
"ContentSecurityPolicy": "default-src 'self'; form-action 'self' https://ikiform.com; connect-src 'self' https://ikiform.com"
}
}
}aws cloudfront create-response-headers-policy --response-headers-policy-config file://csp-policy.jsonOverride: true remplace toute CSP envoyée par l'origine. Avec une origine S3 nue, il n'y en a pas, mais cela garde la politique aux commandes si vous changez d'origine plus tard.Vérifiez que tout fonctionne
- Ajoutez les domaines du tableau ci-dessus, plus
localhostpendant vos tests. - Envoyez depuis votre domaine CloudFront. Vous devez arriver sur
thanks.htmlsur votre propre domaine. - Si vous gardez aussi le website endpoint nu public, envoyez depuis celui-ci et vérifiez que vous arrivez sur la page définie dans Redirect after submit.
- Ouvrez Submissions dans le tableau de bord. La nouvelle soumission y est, avec tous les champs envoyés.
- Vérifiez la boîte de réception de chaque destinataire des notifications. Chacun reçoit un e-mail avec les champs, et Reply répond à l'expéditeur quand le formulaire a un champ
email. - Rien n'est arrivé ? Passez le filtre de statut du tableau de bord sur Spam. Le spam reçoit la même réponse de succès qu'une vraie soumission.
Pièges
| Problème | Que faire |
|---|---|
405 Method Not Allowed avec Code: MethodNotAllowed | Le formulaire a envoyé vers le bucket. CloudFront sert peut-être encore l'ancien contact.html ; invalidez-le. |
AccessDenied ou 403 après la redirection | La redirection pointe vers un dossier comme /thanks/ sur une distribution CloudFront avec une origine REST. Faites-la pointer vers thanks.html. |
| 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 spam | Le 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. |
Questions
Non. Les website endpoints S3 ne prennent en charge que les requêtes GET et HEAD : un POST reçoit donc 405 MethodNotAllowed. Faites pointer le formulaire vers un backend de formulaires, ou construisez une API avec Lambda.
Non. Le formulaire envoie aussi à Ikiform depuis une page http. CloudFront vous donne le https, ce qui permet à Ikiform de suivre un _redirect vers votre propre page de remerciement.
Cela fonctionne et garde tout chez AWS, mais vous construisez vous-même la validation, le filtrage du spam, le stockage et les nouvelles tentatives, et SES exige un expéditeur vérifié. Un backend de formulaires demande moins de maintenance pour un formulaire de contact.
Possiblement, jusqu'à l'expiration de la copie en cache. Invalidez contact.html après chaque modification, ou téléversez le HTML avec un max-age Cache-Control court pour que les nouveaux formulaires soient en ligne rapidement.
Non, il n'y a pas d'offre gratuite. Les tests sont gratuits : vous pouvez envoyer 50 soumissions de test par mois depuis localhost avant de payer. Pour passer en production, Pro commence à 6 $/mois pour 500 soumissions, ou vous pouvez payer une seule fois 10 000 soumissions pour 49 $ ou 50 000 soumissions pour 149 $, avec des crédits qui n'expirent jamais.
Une étape vous bloque, ou vous voulez un guide pour votre cas ? Écrivez à hello@ikiform.com.