Construire des formulaires avec des routes d'API
Un formulaire HTML amène le navigateur à rafraîchir la page ou à naviguer vers une nouvelle page. Pour envoyer les données du formulaire au point de terminaison de l'API, vous devez intercepter la soumission du formulaire à l'aide de JavaScript.
Cette méthode vous montre comment envoyer les données du formulaire au point de terminaison de l'API et comment traiter ces données.
Prérequis
- Un projet avec un adaptateur pour le rendu à la demande
- Un projet avec une intégration Framework UI installée
Recette
Créez un point de terminaison d'API
POSTdans/api/feedbackqui recevra les données du formulaire. Utilisezrequest.formData()pour les traiter. Assurez-vous de valider les valeurs du formulaire avant de les utiliser.Cet exemple envoie un objet JSON avec un message au client.
export const prerender = false; // Pas nécessaire en mode `server` import type { APIRoute } from "astro"; export const POST: APIRoute = async ({ request }) => { const data = await request.formData(); const name = data.get("name"); const email = data.get("email"); const message = data.get("message"); // Valider les données - vous voudrez probablement faire plus que cela if (!name || !email || !message) { return new Response( JSON.stringify({ message: "Champs obligatoires manquants", }), { status: 400 } ); } // Faire quelque chose avec les données, puis renvoyer une réponse positive return new Response( JSON.stringify({ message: "Succès !" }), { status: 200 } ); };Créez un composant de formulaire en utilisant votre framework UI. Chaque entrée doit avoir un attribut
namequi décrit la valeur de cette entrée.Veillez à inclure un élément
<button>ou<input type="submit">pour soumettre le formulaire.export default function Form() { return ( <form> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> </form> ); }export default function Form() { return ( <form> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> </form> ); }export default function Form() { return ( <form> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> </form> ); }<form> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> </form><template> <form> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> </form> </template>Créez une fonction qui accepte un événement submit, puis passez-la comme gestionnaire
submità votre formulaire.Dans la fonction :
- Appelez
preventDefault()sur l'événement pour remplacer le processus de soumission par défaut du navigateur. - Créez un objet
FormDataet envoyez-le dans une requêtePOSTà votre point de terminaison en utilisantfetch().
import { useState } from "preact/hooks"; export default function Form() { const [responseMessage, setResponseMessage] = useState(""); async function submit(e: SubmitEvent) { e.preventDefault(); const formData = new FormData(e.target as HTMLFormElement); const response = await fetch("/api/feedback", { method: "POST", body: formData, }); const data = await response.json(); if (data.message) { setResponseMessage(data.message); } } return ( <form onSubmit={submit}> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> {responseMessage && <p>{responseMessage}</p>} </form> ); }import { useState } from "react"; import type { FormEvent } from "react"; export default function Form() { const [responseMessage, setResponseMessage] = useState(""); async function submit(e: FormEvent<HTMLFormElement>) { e.preventDefault(); const formData = new FormData(e.target as HTMLFormElement); const response = await fetch("/api/feedback", { method: "POST", body: formData, }); const data = await response.json(); if (data.message) { setResponseMessage(data.message); } } return ( <form onSubmit={submit}> <label htmlFor="name"> Nom <input type="text" id="name" name="name" autoComplete="name" required /> </label> <label htmlFor="email"> Email <input type="email" id="email" name="email" autoComplete="email" required /> </label> <label htmlFor="message"> Message <textarea id="message" name="message" autoComplete="off" required /> </label> <button>Envoyer</button> {responseMessage && <p>{responseMessage}</p>} </form> ); }import { createSignal, createResource, Suspense } from "solid-js"; async function postFormData(formData: FormData) { const response = await fetch("/api/feedback", { method: "POST", body: formData, }); const data = await response.json(); return data; } export default function Form() { const [formData, setFormData] = createSignal<FormData>(); const [response] = createResource(formData, postFormData); function submit(e: SubmitEvent) { e.preventDefault(); setFormData(new FormData(e.target as HTMLFormElement)); } return ( <form onSubmit={submit}> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> <Suspense>{response() && <p>{response().message}</p>}</Suspense> </form> ); }<script lang="ts"> let responseMessage: string; async function submit(e: SubmitEvent) { e.preventDefault(); const formData = new FormData(e.currentTarget as HTMLFormElement); const response = await fetch("/api/feedback", { method: "POST", body: formData, }); const data = await response.json(); responseMessage = data.message; } </script> <form on:submit={submit}> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> {#if responseMessage} <p>{responseMessage}</p> {/if} </form><script setup lang="ts"> import { ref } from "vue"; const responseMessage = ref<string>(); async function submit(e: Event) { e.preventDefault(); const formData = new FormData(e.currentTarget as HTMLFormElement); const response = await fetch("/api/feedback", { method: "POST", body: formData, }); const data = await response.json(); responseMessage.value = data.message; } </script> <template> <form @submit="submit"> <label> Nom <input type="text" id="name" name="name" required /> </label> <label> Email <input type="email" id="email" name="email" required /> </label> <label> Message <textarea id="message" name="message" required /> </label> <button>Envoyer</button> <p v-if="responseMessage">{{ responseMessage }}</p> </form> </template>- Appelez
Importez et incluez votre composant
<FeedbackForm />dans une page. Assurez-vous d'utiliser une directiveclient:*pour garantir que la logique du formulaire est hydratée quand vous le souhaitez.--- import FeedbackForm from "../components/FeedbackForm" --- <FeedbackForm client:load />--- import FeedbackForm from "../components/FeedbackForm" --- <FeedbackForm client:load />--- import FeedbackForm from "../components/FeedbackForm" --- <FeedbackForm client:load />--- import FeedbackForm from "../components/FeedbackForm.svelte" --- <FeedbackForm client:load />--- import FeedbackForm from "../components/FeedbackForm.vue" --- <FeedbackForm client:load />