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

Svelte项目中ActionData导入失败及form变量获取问题

问题原因及解决办法

核心问题所在

  1. fail()函数用错了地方:fail()是SvelteKit服务器端Action的专属API,你把它写在前端组件的loginWithEmail函数里完全不会生效——前端没有SvelteKit的Action上下文,所以form变量始终是null。
  2. ActionData类型不存在的原因:ActionData是SvelteKit自动生成的类型,只有当你在对应页面的+page.server.ts里定义了服务器Action时,才会出现在./$types里。你现在没有服务器Action,自然找不到这个导出。

两种解决路径

路径一:改用SvelteKit服务器Action(推荐,符合框架规范)

  1. 在/login目录下创建+page.server.ts,把登录逻辑移到服务器端:
import { fail, redirect } from '@sveltejs/kit';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '$lib/firebase'; // 替换成你Firebase auth实例的实际导出路径

export const actions = {
    default: async ({ request }) => {
        const formData = await request.formData();
        const email = formData.get('email') as string;
        const password = formData.get('password') as string;

        try {
            await signInWithEmailAndPassword(auth, email, password);
            // 服务器端操作session需用event.locals,建议先在hooks.ts配置同步逻辑
            throw redirect(303, '/');
        } catch (error: any) {
            const code = error.code;
            if (!code) {
                return fail(400, { email, unknown: true });
            }

            switch (code) {
                case 'auth/wrong-password':
                    return fail(400, { email, wrongPassword: true });
                case 'auth/missing-password':
                    return fail(400, { email, missingPassword: true });
                case 'auth/invalid-email':
                    return fail(400, { email, invalidEmail: true });
                default:
                    return fail(400, { email, unknown: true });
            }
        }
    }
};
  1. 修改+page.svelte的表单和逻辑:
    • 不需要自定义loginWithEmail函数,表单直接用method="POST"(服务器Action默认接收POST请求)
    • 此时./$types会自动生成ActionData类型,可正常导入使用:
<script lang="ts">
    import type { ActionData } from './$types';
    export let form: ActionData;
</script>

<form method="POST">
    {#if form?.wrongPassword}<p class="error">Wrong password.</p>{/if}
    {#if form?.missingPassword}<p class="error">Missing password.</p>{/if}
    {#if form?.invalidEmail}<p class="error">Malformed email.</p>{/if}
    {#if form?.unknown}<p class="error">Authentication error.</p>{/if}

    <input name="email" type="text" placeholder="Email" value={form?.email ?? ''} />
    <input name="password" type="password" placeholder="Password" />
    <button type="submit">Login</button>
</form>
  • 注意:表单输入需加name属性,服务器端才能通过formData获取值;value={form?.email ?? ''}用于错误时预填用户输入的邮箱。

路径二:前端自行处理错误状态(不使用服务器Action)

如果坚持在前端处理登录逻辑,不要用SvelteKit的form变量,自己定义前端错误状态:

<script lang="ts">
    let email = '';
    let password = '';
    let error: { wrongPassword?: boolean; missingPassword?: boolean; invalidEmail?: boolean; unknown?: boolean } | null = null;

    async function loginWithEmail() {
        error = null;
        try {
            const result = await signInWithEmailAndPassword(auth, email, password);
            const { user } = result;
            await session.set({
                loggedIn: true,
                user: {
                    displayName: user?.displayName,
                    email: user?.email,
                    photoURL: user?.photoURL,
                    uid: user?.uid
                }
            });
            goto('/');
        } catch (err: any) {
            const code = err.code;
            if (!code) {
                error = { unknown: true };
                return;
            }

            switch (code) {
                case 'auth/wrong-password':
                    error = { wrongPassword: true };
                    break;
                case 'auth/missing-password':
                    error = { missingPassword: true };
                    break;
                case 'auth/invalid-email':
                    error = { invalidEmail: true };
                    break;
                default:
                    error = { unknown: true };
                    break;
            }
        }
    }
</script>

<form on:submit|preventDefault={loginWithEmail}>
    {#if error?.wrongPassword}<p class="error">Wrong password.</p>{/if}
    {#if error?.missingPassword}<p class="error">Missing password.</p>{/if}
    {#if error?.invalidEmail}<p class="error">Malformed email.</p>{/if}
    {#if error?.unknown}<p class="error">Authentication error.</p>{/if}

    <input bind:value={email} type="text" placeholder="Email" />
    <input bind:value={password} type="password" placeholder="Password" />
    <button type="submit">Login</button>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:18:25