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
相关产品推荐
相关产品推荐

