SvelteKit表单集成ReCaptcha v3:异步token无法传递至服务端问题
在SvelteKit表单中集成ReCaptcha v3并传递Token到服务端
你遇到的核心问题是异步操作未等待完成就执行后续逻辑:checkCaptcha是异步获取Token的过程,但你调用它后直接往formData里添加token,此时Token还未生成,自然无法传递到服务端。
解决方案:将异步逻辑转为可等待的Promise
修改checkCaptcha函数使其返回Promise,在use:enhance中等待Token生成后再处理表单数据:
<script> let key = '你的ReCaptcha密钥'; // 替换为实际密钥 // 改造为返回Promise的异步函数 async function checkCaptcha() { return new Promise((resolve) => { grecaptcha.ready(() => { grecaptcha.execute(key, { action: "submit" }).then((token) => { resolve(token); }); }); }); } </script> <svelte:head> <script src="https://www.google.com/recaptcha/api.js?render={key}" async defer></script> </svelte:head> <form method="POST" use:enhance={async ({ formData }) => { // 等待ReCaptcha Token生成 const token = await checkCaptcha(); // 将Token添加到表单数据 formData.append("token", token); return async ({ result, update }) => { update(); }; }}> <!-- 表单内容 --> <button type="submit">提交</button> </form>
关键改动说明
- 封装异步逻辑为Promise:让
checkCaptcha返回Promise,确保我们可以用await等待Token生成完成。 - 在use:enhance中等待Token:先执行
await checkCaptcha()拿到有效Token,再将其添加到formData,保证提交时Token已存在。
服务端验证补充(可选)
在+page.server.js的表单Action中,需要验证Token的有效性:
export async function POST({ request }) { const formData = await request.formData(); const token = formData.get('token'); // 调用ReCaptcha官方验证接口 const verifyRes = await fetch('https://www.google.com/recaptcha/api/siteverify', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `secret=你的ReCaptcha密钥&response=${token}` }); const verifyResult = await verifyRes.json(); if (!verifyResult.success) { return fail(400, { error: '验证码验证失败' }); } // 后续表单业务逻辑处理 }
内容的提问来源于stack exchange,提问作者Hubert
相关产品推荐
相关产品推荐

