繁体   English   中英

如何在 SvelteKit 联系表中获取 recaptcha 令牌

[英]How to get recaptcha token in SvelteKit contact form

我正在使用 SvelteKit 开发一个静态网站,以获得我的第一种瘦身方法。 我几乎让一切都按预期工作。 除了联系表格上的 recaptcha 保护之外的所有内容。

我可以获得recaptcha令牌,但在将其传递给formData请求时丢失了它。 我的相对代码是:

<script lang="ts">
    import * as yup from "yup";
    import {createForm, ErrorMessage} from "svelte-forms-lib";
    ...

    function getCaptcha(){
        grecaptcha.ready(function () {
            grecaptcha.execute('recaptcha-key', { action: 'contactForm' })
                .then(function (token) {

                    console.log(token) // here I get the token
                    return token;
                });
        });
    }

    const  sendMail= (values)=>
    {
        const url = '/sendmail.php';

    const formData = new FormData();
    let token = getCaptcha();
    console.log('token: '+token); // here token is null

    formData.append("token", token);

    fetch(url, {
        method: 'post',
    body: formData,
        })
    .then(function (response) {
        console.debug(response.status)
    })
    .catch(function (e) {
        sendError = true;
    console.debug(e);
        });
    }
</script>

表单提交工作正常,显然,除了 recaptcha 令牌。

感谢您提供有关如何解决它的任何想法。

token为空,因为您的getCaptcha函数实际上并未返回任何内容,因为您正在使用回调来获取令牌。

function getCaptcha(){  // <- this function isn't returning anything
    grecaptcha.ready(function () {
        grecaptcha.execute('recaptcha-key', { action: 'contactForm' })
            .then(function (token) {  // <- this function returns, but the value isn't going anywhere
                console.log(token);
                return token;
            });
    });
}

要解决此问题,您可能需要考虑对 promise 使用async / await语法。 如果您有兴趣, MDN 有一篇很棒的文章

你可能想要做这样的事情:

async function getCaptcha(){
    await new Promise((resolve, reject) => {
        // grecaptcha.ready needs a callback so we create a promise to await
        grecaptcha.ready(resolve);
    });
    // grecaptcha.execute returns a promise so we can await it
    const token = await grecaptcha.execute('recaptcha-key', { action: 'contactForm' });
    console.log(token);
    return token;
}

const sendMail = async (values) => {
    const url = '/sendmail.php';

    const formData = new FormData();

    let token = await getCaptcha();
    console.log('token: ' + token);

    formData.append("token", token);

    // you have a few options for converting
    // the Promise.catch()
    // you can use a try {} catch {} block
    // or you can use .catch() on this sendMail function
    try {
        const response = fetch(url, {
            method: 'post',
            body: formData,
        });
        console.debug(response.status);
    } catch (e) {
        sendError = true;
        console.debug(e);
    }
}

请记住,这将使sendMail函数成为async函数,这意味着您必须await对它的调用,或使用sendMail().then() 我相信也可以直接在同步代码中调用async函数并让它们运行,只是不能保证函数中的内容会在调用后的代码之前运行。

为了澄清起见,我的最终代码在提交功能方面略有不同,我将其发布以供将来参考,以防万一。

 async function getCaptcha(){ await new Promise((resolve, reject) => { // grecaptcha.ready needs a callback so we create a promise to await grecaptcha.ready(resolve); }); // grecaptcha.execute returns a promise so we can await it const token = await grecaptcha.execute('site-key', { action: 'contactForm' }); return token; } const sendMail = async (values) => { const url = '/sendmail.php'; const formData = new FormData(); let token = await getCaptcha(); formData.append("name", values.name); formData.append("surname", values.surname); formData.append("email", values.email); formData.append("phone", values.phone); formData.append("message", values.message); formData.append("token", token); formData.append("action", "contactForm"); // you have a few options for converting // the Promise.catch() // you can use a try {} catch {} block // or you can use .catch() on this sendMail function try { let response = await fetch(url, { method: 'post', body: formData, }); if(response.status == 202){ sendSuccess = true; document.querySelector('form').reset(); } if(response.status == 400){ sendError = true; } } catch(err) { sendError = true; } }

您可以使用svelte-recaptcha-v2代替自己处理。

存储库

https://github.com/basaran/svelte-recaptcha-v2

演示

https://basaran.github.io/svelte-recaptcha-v2/demo

P.S 我是这个包的作者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM