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

SvelteKit联系表单中ReCAPTCHA Token获取后传递丢失问题的解决方法

问题分析与解决思路

兄弟,你的问题核心是异步操作处理不当!getCaptcha里的grecaptcha.execute是异步执行的,但你现在用同步方式获取返回值,自然会拿到null——因为函数还没等异步请求完成就已经返回了。

为什么会出现这个问题?

你看,grecaptcha.ready和.then都是异步回调,当你执行let token = getCaptcha()时,getCaptcha函数并没有等待异步操作完成就提前返回了(而且原函数里也没返回任何异步对象),所以token必然是undefined。

修复步骤

1. 把getCaptcha改成返回Promise的异步函数

我们需要让这个函数等待ReCAPTCHA的token生成完成后再返回结果:

async function getCaptcha(): Promise<string> {
    // 先等待grecaptcha初始化完成
    await new Promise(resolve => grecaptcha.ready(resolve));
    // 执行获取token的操作并返回
    const token = await grecaptcha.execute('recaptcha-key', { action: 'contactForm' });
    console.log(token); // 这里依然能正常打印token
    return token;
}

或者用传统Promise写法也可以:

function getCaptcha(): Promise<string> {
    return new Promise((resolve) => {
        grecaptcha.ready(function () {
            grecaptcha.execute('recaptcha-key', { action: 'contactForm' })
                .then(function (token) {
                    console.log(token);
                    resolve(token);
                });
        });
    });
}

2. 修改sendMail函数,用await等待token返回

因为调用了异步函数,sendMail也要改成异步函数,确保拿到token后再组装FormData:

const sendMail = async (values) => {
    const url = '/sendmail.php';
    const formData = new FormData();
    
    try {
        // 等待token获取完成
        let token = await getCaptcha();
        console.log('token: ' + token); // 现在能拿到正确的token了
        
        // 把token和表单字段都加入FormData
        formData.append("token", token);
        // 这里记得把values里的其他表单字段也加进去(比如姓名、邮箱、消息内容)
        Object.entries(values).forEach(([key, value]) => {
            formData.append(key, value);
        });
        
        // 发送请求
        const response = await fetch(url, {
            method: 'post',
            body: formData,
        });
        console.debug(response.status);
        // 这里可以添加提交成功后的逻辑(比如提示用户)
    } catch (e) {
        sendError = true;
        console.debug(e);
    }
};

额外注意事项

  • 确保页面已经正确加载了ReCAPTCHA的脚本,不然grecaptcha对象会不存在导致报错。
  • 后端的sendmail.php一定要记得验证这个token!调用Google的ReCAPTCHA验证接口(https://www.google.com/recaptcha/api/siteverify),不要只接收token就直接发送邮件,不然ReCAPTCHA的防护就形同虚设了。
  • 如果是通过表单提交触发sendMail,记得在提交事件里阻止默认行为(event.preventDefault()),避免页面刷新打断异步操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 10:18:11