跳转到内容

使用 API 路由构建表单

一个 HTML 表单会导致浏览器刷新页面或跳转到新页面。为了将表单数据发送到 API 端点,就必须要使用 JavaScript 拦截提交的表单。

本节示例向你展示了如何发送表单数据到一个 API 端点,并处理这些数据。

前期准备

操作步骤

  1. /api/feedback 上创建一个 POST API 端点,用于接收表单数据。然后使用 request.formData() 处理表单数据。但在你使用表单值之前,请确保对其进行必要的校验。

    在这个示例中会向客户端发送一个包含响应消息的 JSON 对象。

    export const prerender = false; // '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");
      // Validate the data - you'll probably want to do more than this
      if (!name || !email || !message) {
        return new Response(
          JSON.stringify({
            message: "Missing required fields",
          }),
          { status: 400 }
        );
      }
      // Do something with the data, then return a success response
      return new Response(
        JSON.stringify({
          message: "Success!"
        }),
        { status: 200 }
      );
    };
  2. 使用你的 UI 框架创建一个表单组件。每个输入字段都应该有一个描述该输入值的 name 属性。

    请确保表单中包含一个 <button><input type="submit"> 元素,用于提交表单。

      export default function Form() {
        return (
          <form>
            <label>
              Name
              <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>Send</button>
          </form>
        );
      }
  3. 创建一个函数以接受提交事件(submit event),然后将其作为 submit 事件处理器传递给你的表单。

    在函数中:

    • 调用事件的 preventDefault() 方法,以覆盖浏览器的默认提交过程。
    • 创建一个 FormData 对象,并使用 fetch 将其以 POST 请求发送到你的端点。
      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>
              Name
              <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>Send</button>
            {responseMessage && <p>{responseMessage}</p>}
          </form>
        );
      }
  4. 在一个页面中导入并包含你的 <FeedbackForm /> 组件。请确认使用了 client:* 指令以确保表单逻辑能在你需要的时候被激活。

      ---
      import FeedbackForm from "../components/FeedbackForm"
      ---
      <FeedbackForm client:load />
贡献 社区 赞助