web-dev-qa-db-fra.com

Vue.js google reCaptcha callback

J'essaie de faire en sorte que callback recaptcha fonctionne avec vue.js dans un composant. Le captcha lui-même fonctionne, mais pas le rappel que je définis dans l'attribut data-callback.

J'ai tout essayé, mais j'ai toujours l'erreur ReCAPTCHA couldn't find user-provided function: dothisthat.

Voici le composant

<script>
    function dothisthat (){
            alert(312);
        }
</script>

<template>
    <div class="well main-well">
        <h4>Captcha</h4>
        <p class="small">You must complete the captcha to finish your booking.</p>
        <div id="captcha-wrapper">
            <div class="g-recaptcha" :data-sitekey="captchaKey" data-callback="dothisthat"></div>
        </div>
    </div>
</template>
<script>
     function dothisthat (){
        alert(123);
    }
    import * as filters from '../../../filters';
    import Translation from '../../../Translation';

    export default {
        name: 'Captcha',
        props: {
        },
        computed: {
            captchaKey: function() {
                return this.$store.getters.captcha;
            }
        },
        methods: {
            dothisthat: function(){
                return function() {
                    console.log("123");
                };
            }
        },
        mounted(){

            function dothisthat() {
                alert(123);
            }
            $(function() {
                function dothisthat() {
                    alert(123);
                }
            });
        }
    }
</script>

Aucune des fonctions dothisthat n'est appelée. Qu'est-ce que je fais mal?

13
user2209644

J'ai rencontré ce problème aussi et il m'a fallu 2 jours pour le résoudre. 

Je vais donc donner ici une réponse générale pour intégrer recaptcha avec vue.js à partir de zéro, étape par étape, afin de faciliter la tâche des personnes qui se retrouveront dans la même situation à l’avenir (je suppose que vue-cli est utilisé ici).

Note: J'utilise ici l'invisible recaptcha mais le processus est assez similaire à celui normal 

Étape 1:  

ajoutez l'API javascript Recaptcha à votre index.html

index.html

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

Étape 2:  

créer un composant appelé Recaptcha ou le nom que vous souhaitez appeler (le fait de rendre un composant plus facile à lire, à gérer et à ajouter à recaptcha sur plusieurs pages, si vous en avez besoin)

Recaptcha.vue

<template>
  <div 
  id="g-recaptcha"
  class="g-recaptcha"
  :data-sitekey="sitekey">
  </div>
</template>

<script>
export default {
  data () {
    return {
      sitekey: '6LfAEj0UAAAAAFTGLqGozrRD8ayOy*********',
      widgetId: 0
    }
  },
  methods: {
    execute () {
      window.grecaptcha.execute(this.widgetId)
    },
    reset () {
      window.grecaptcha.reset(this.widgetId)
    },
    render () {
      if (window.grecaptcha) {
        this.widgetId = window.grecaptcha.render('g-recaptcha', {
          sitekey: this.sitekey,
          size: 'invisible',
          // the callback executed when the user solve the recaptcha
          callback: (response) => {
            // emit an event called verify with the response as payload
            this.$emit('verify', response)
            // reset the recaptcha widget so you can execute it again
            this.reset() 
          }
        })
      }
    }
  },
  mounted () {
    // render the recaptcha widget when the component is mounted
    this.render()
  }
}
</script>

Étape 3:  

Importez le composant recaptcha et ajoutez-le à votre page (composant parent).

page.vue

<template>
  <div>
    <h1>Parent component (your page)</h1>
    <button @click="executeRecaptcha">execute recaptcha</button>
    <!-- listen to verify event emited by the recaptcha component -->
    <recaptcha ref="recaptcha" @verify="submit"></recaptcha>
  </div>
</template>

<script>
import Recaptcha from 'recaptcha'
export default {
  components: {
    Recaptcha
  },
  methods: {
    // send your recaptcha token to the server to verify it
    submit (response) {
      console.log(response)
    },
    // execute the recaptcha widget
    executeRecaptcha () {
      this.$refs.recaptcha.execute()
    }
  }
}
</script>
15
Abdelaziz Mokhnache

Je n'utilise pas de composant, mais j'ai eu le même problème, et finalement je le résous comme suit:

HTML

<div id="recaptcha" class="g-recaptcha"></div>
<button id="submit" @click="validate">Submit</button>
<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>

JS

// ...
mounted: function() {
    this.initReCaptcha();
},
methods: {
    initReCaptcha: function() {
        var self = this;
        setTimeout(function() {
            if(typeof grecaptcha === 'undefined') {
                self.initReCaptcha();
            }
            else {
                grecaptcha.render('recaptcha', {
                    sitekey: 'SITE_KEY',
                    size: 'invisible',
                    badge: 'inline',
                    callback: self.submit
                });
            }
        }, 100);
    },
    validate: function() {
        // your validations...
        // ...
        grecaptcha.execute();
    },
    submit: function(token) {
        console.log(token);
    }
},
13
Lay

Si vous recherchez uniquement la valeur de réponse de recaptcha afin de la valider côté serveur, une solution simple consiste à placer votre élément recaptcha dans un formulaire et à obtenir la valeur de réponse de l'élément cible de l'élément submit event.

<form class="container"
  @submit="checkForm"
  method="post"
>

... // other elements of your form 

<div class="g-recaptcha" data-sitekey="your_site_key"></div>

<p>
    <input class="button" type="submit" value="Submit">
</p>
</form>

Et dans la méthode checkForm:

methods : {
        checkForm: function (event) {
            recaptcha_response_value = event.target['g-recaptcha-response'].value

           ...
         }
1
Kasrâmvd