You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Astro中使用PRG模式与Actions时,如何获取表单成功提交的数据?

如何在Astro表单提交成功时通过PRG中间件获取表单数据

要解决这个问题,你只需对官方提供的PRG中间件做简单扩展,把表单提交的原始数据和action结果一起持久化存储,重定向后的GET请求就能拿到这些数据用于回显。具体操作如下:

1. 修改PRG中间件,添加表单数据存储逻辑

在中间件处理表单提交的分支里,先提取原始表单数据,再和action结果一起存入Netlify Blob:

import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
import { randomUUID } from "node:crypto";
import { getStore } from "@netlify/blobs";

export const onRequest = defineMiddleware(async (context, next) => {
  // Skip requests for prerendered pages
  if (context.isPrerendered) return next();

  const { action, setActionResult, serializeActionResult } =
    getActionContext(context);
  // Create a Blob store to persist action results with Netlify Blob
  const actionStore = getStore("action-session");

  // If an action result was forwarded as a cookie, set the result
  // to be accessible from `Astro.getActionResult()`
  const sessionId = context.cookies.get("action-session-id")?.value;
  const session = sessionId
    ? await actionStore.get(sessionId, {
        type: "json",
      })
    : undefined;

  if (session) {
    // 扩展action结果,把表单数据附加进去
    const extendedResult = {
      ...session.actionResult,
      formData: session.formData
    };
    setActionResult(session.actionName, extendedResult);

    // Optional: delete the session after the page is rendered.
    // Feel free to implement your own persistence strategy
    await actionStore.delete(sessionId);
    context.cookies.delete("action-session-id");
    return next();
  }

  // If an action was called from an HTML form action,
  // call the action handler and redirect to the destination page
  if (action?.calledFrom === "form") {
    // 提取表单提交的原始数据并转为普通对象
    const formData = await context.request.formData();
    const formDataObj = Object.fromEntries(formData.entries());

    const actionResult = await action.handler();

    // 同时存储action结果和表单数据
    const sessionId = randomUUID();
    await actionStore.setJSON(sessionId, {
      actionName: action.name,
      actionResult: serializeActionResult(actionResult),
      formData: formDataObj // 新增:存储表单数据
    });

    // Pass the session ID as a cookie
    // to be retrieved after redirecting to the page
    context.cookies.set("action-session-id", sessionId);

    // Redirect back to the previous page on error
    if (actionResult.error) {
      const referer = context.request.headers.get("Referer");
      if (!referer) {
        throw new Error(
          "Internal: Referer unexpectedly missing from Action POST request.",
        );
      }
      return context.redirect(referer);
    }
    // Redirect to the destination page on success
    return context.redirect(context.originPathname);
  }

  return next();
});

2. 在Astro组件中获取表单数据

重定向完成后,在表单组件里通过Astro.getActionResult()就能拿到包含表单数据的结果:

---
import { getActionResult } from 'astro:actions';
const result = await getActionResult('你的Action名称');
// 提交成功时可直接获取表单数据
const submittedFormData = result?.formData;
---

<form method="POST" action="/api/你的Action路径">
  <input type="text" name="username" value={submittedFormData?.username || ''} />
  <input type="email" name="email" value={submittedFormData?.email || ''} />
  <button type="submit">提交</button>
</form>

{result?.success && <p>提交成功!你输入的用户名是:{submittedFormData?.username}</p>}

核心逻辑说明

  • 中间件新增了表单数据的提取、转换和存储步骤,确保数据能跟随action结果一起传递到重定向后的页面
  • 重定向后的GET请求中,我们把表单数据附加到action结果里,让组件可以直接读取使用
  • 这种方案完全基于官方PRG模式扩展,不需要依赖transition:persist,适配你的需求

内容的提问来源于stack exchange,提问作者Brendan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 11:45:54