ReCaptcha v2 不会在 vue-router 导航中加载

ReCaptcha v2 won't load in vue-router navigation

我正在使用 Google ReCaptcha v2,我正在将其集成到注册过程中。因此,当用户进入 /register 时,它会加载 RegisterComponent.

但是,当我在主页并通过按钮导航到 /register 时,reCaptcha 不会加载。为什么会这样?

我正在加载 layouts.master.php 中的脚本:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

并像这样在注册组件中加载 reCaptcha:

<div class="field">
    <div class="control" id="recaptcha-reg">
        <div class="g-recaptcha" data-sitekey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"></div>
        <span v-if="regErrors.captcha" v-for="error in errors">{{ error }}</span>
    </div>
</div>

然后使用 PHP 验证此 reCaptcha。所以,没有 JS 逻辑!请帮忙!

如果有人遇到同样的问题,请按以下方法解决:

  • 将 id 分配给您的 reCaptcha 小部件。
  • 然后在创建组件时,运行 setTimeout 渲染小部件。

示例:

<div id="recaptcha-main" class="g-recaptcha" data-sitekey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"></div>

然后在您要加载验证码的组件中:

created() {
    setTimeout(() => {
        grecaptcha.render('recaptcha-main'); // 'recaptcha-main' is the id that was assigned to the widget
    }, 2000);
}

就是这样!

已更新 - 最佳方法

而不是使用 setTimeout,而是使用 nextTick(),基本上 运行s 仅在包含视图之后。 children 已完成加载。

您分配 id,然后 运行 在您的 created 挂钩中:

this.$nextTick(function () {
    grecaptcha.render('recaptcha-main');
})

setTimeout 的缺点是 运行 仅在指定时间之后。比如说 1 秒。因此,如果您的组件需要超过 1 秒的时间才能完全加载,那么 setTimeout 可能无法在此处工作,因为它将在 1 秒后立即执行。

我希望这对你有用:)

@Damon 的回答有效而且很棒 - 我想我只是 post 一些 vue 组件代码来帮助其他人实现它:

created() { // in whatever component has a recaptcha
    window.sendMsg = this.sendMsg // making the callback function from the vue object available to the google script in the global scope.
    console.log('grecaptcha', grecaptcha)
    this.$nextTick(function() {
        grecaptcha.ready(function() { // making sure the recapcha script is loaded
            try {
                grecaptcha.render('invisibleRecaptcha1') //render the plain-jane recaptcha element with the given id
            } catch (err) { // dont care about errors, because the worst that can happen is maybe it already rendered once.
                err
            }
        })
    })
}

这个想法只是你应该像往常一样把google脚本标签放在head中,然后使用最简单的静态集成标签:

<button id="invisibleRecaptcha1" class="g-recaptcha" data-sitekey="6Lc7hdkZ**********************" data-callback="sendMsg" data-action="submit">Shout!</button>

其中 sendMsg 是您使用 recaptcha 保护的任何功能。