Superforms、zod与Server Actions提交ID失败求助
问题分析与解决方案
你的核心问题是单个表单内存在多个同名的exampleId隐藏输入框,点击按钮提交时浏览器会将所有输入框的值以数组形式发送,但你的Zod Schema要求exampleId是单个24位字符串,客户端验证直接失败,导致SuperForms的enhance拦截了表单提交,最终Server Action完全没触发,同时SuperDebug显示exampleId为空(数组不符合字符串验证规则,被清空)。
解决方案一:为每个ID创建独立表单
这是最直接的修复方式,让每个按钮对应单独的表单,确保每次提交仅发送当前ID:
修改example-component.svelte的表单部分:
<script lang="ts"> // 原有代码保持不变 </script> {#each exampleArray as item} <form method="POST" action="?/exampleAction" use:enhance> <input type="hidden" name="exampleId" value="{item}"/> <button type="submit" >{item}</button><br /> </form> {/each} <SuperDebug data={formData} />
解决方案二:单表单动态设置提交值
如果希望保留单个表单结构,可以通过点击事件动态更新表单的exampleId值后再提交:
修改example-component.svelte:
<script lang="ts"> // 原有代码保持不变 function handleSubmit(item: string) { $formData.exampleId = item; document.querySelector('form')?.submit(); } </script> <form method="POST" action="?/exampleAction" use:enhance> <input type="hidden" name="exampleId" bind:value={$formData.exampleId}/> {#each exampleArray as item} <button type="button" on:click={() => handleSubmit(item)}>{item}</button><br /> {/each} </form> <SuperDebug data={formData} />
这里将按钮类型改为button(避免默认提交行为),点击时先更新表单的exampleId值,再手动触发表单提交,确保每次仅发送当前点击的ID。
可选优化:统一服务端验证逻辑
建议在Server Action中使用superValidate处理表单数据,和客户端共用一套验证规则,逻辑更统一:
修改+page.server.ts的exampleAction:
export const actions: Actions = { exampleAction: async ({ request }) => { const form = await superValidate(request, zod(exampleSchema)); if (!form.valid) { return fail(400, { form }); } console.log('Submitted ID:', form.data.exampleId); return { success: true, form }; } };
内容的提问来源于stack exchange,提问作者redmamoth
相关产品推荐
相关产品推荐

