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

SvelteKit页脚表单无需use:enhance避免跳转获取服务端响应

解决方案

要在不使用use:enhance的前提下实现表单提交不跳转、且从$page.form获取服务端回复,需要手动处理表单提交流程,并结合SvelteKit的状态同步机制,具体步骤如下:

1. 手动拦截表单提交事件

在组件中监听表单的submit事件,阻止默认跳转行为,手动收集表单数据并发起请求:

<script>
  import { page, invalidateAll } from '$app/stores';
  // 初始化表单状态为服务端传递的page.form(如果有)
  let form = $page.form ?? {};

  async function handleSubmit(e) {
    // 阻止默认表单提交跳转
    e.preventDefault();
    
    // 收集表单数据
    const formData = new FormData(e.target);
    
    // 发起POST请求到目标action
    const response = await fetch('/contact?/contact', {
      method: 'POST',
      body: formData,
      // 携带会话信息,保持登录状态(如果需要)
      credentials: 'include'
    });

    // 解析服务端响应
    const result = await response.json();
    // 更新组件内表单状态
    form = result.data;

    // 触发页面数据重新加载,让$page.form同步服务端返回的结果
    await invalidateAll();
  }
</script>

<form method="POST" action="/contact?/contact" on:submit={handleSubmit}>
  <!-- 表单输入控件 -->
  <input type="email" name="email" value={form.email ?? ''} />
  <textarea name="message">{form.message ?? ''}</textarea>
  <button type="submit">提交</button>

  <!-- 显示服务端返回的错误或成功信息 -->
  {#if form.error}
    <p style="color: red;">{form.error}</p>
  {/if}
  {#if form.success}
    <p style="color: green;">{form.success}</p>
  {/if}
</form>

2. 修改服务端Action,存储表单结果到Cookie

为了让$page.form能获取到服务端的回复,需要在/contact/+page.server.js的action中,将表单处理结果存储到Cookie(或Session)中,方便其他页面的load函数读取:

import { fail } from '@sveltejs/kit';

export const actions = {
  contact: async ({ request, cookies }) => {
    const data = await request.formData();
    const email = data.get('email');
    const message = data.get('message');

    // 表单验证逻辑
    if (!email || !message) {
      const formData = {
        error: '请填写邮箱和消息内容',
        email: email ?? '',
        message: message ?? ''
      };
      // 将结果存入Cookie,允许客户端读取
      cookies.set('form_result', JSON.stringify(formData), {
        path: '/',
        httpOnly: false,
        maxAge: 60 // 1分钟过期,避免长期留存
      });
      return fail(400, formData);
    }

    // 执行表单提交逻辑(如发送邮件、存入数据库)
    const successData = { success: '消息已成功发送' };
    cookies.set('form_result', JSON.stringify(successData), {
      path: '/',
      httpOnly: false,
      maxAge: 60
    });
    return successData;
  }
};

3. 在页面/布局的Load函数中读取Cookie,更新$page.form

由于页脚通常在布局组件中,需要在+layout.server.js中读取Cookie中的表单结果,返回给$page.form:

export async function load({ cookies }) {
  const formResult = cookies.get('form_result');
  let form = {};

  if (formResult) {
    // 解析Cookie中的表单结果
    form = JSON.parse(formResult);
    // 读取后删除Cookie,避免页面刷新后重复显示
    cookies.delete('form_result', { path: '/' });
  }

  return { form };
}

关键说明

  • 手动处理提交时,必须携带credentials: 'include'以保持会话状态,否则服务端无法识别用户(如果有登录验证需求)。
  • invalidateAll()会触发所有页面数据的重新加载,确保$page.form能同步最新的表单结果。
  • 使用Cookie存储表单结果是为了跨页面传递数据,也可以改用Session存储(需配置SvelteKit的Session机制)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 23:55:22