web-dev-qa-db-de.com

Vue.js google reCaptcha callback

Ich versuche, Recaptcha Callback mit vue.js in einer Komponente arbeiten zu lassen. Das Captcha selbst funktioniert, aber nicht der Rückruf, den ich im data-callback-Attribut definiere.

Ich habe alles versucht, was mir einfällt, aber ich bekomme immer noch den ReCAPTCHA couldn't find user-provided function: dothisthat-Fehler.

Hier ist die Komponente

<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>

Es wird keine der dothisthat-Funktionen aufgerufen. Was mache ich falsch?

13
user2209644

Ich bin auch auf dieses Problem gestoßen und ich habe 2 Tage gebraucht, um es zu lösen. 

Daher werde ich hier eine allgemeine Antwort geben, wie Sie Recaptcha Schritt für Schritt von Grund auf neu in vue.js integrieren. Dies ist eine einfache Anleitung für Personen, die sich in der gleichen Situation befinden werden (ich nehme an, dass hier vue-cli verwendet wird).

Hinweis: Ich verwende hier das unsichtbare Recaptcha, aber der Vorgang ist dem normalen ziemlich ähnlich 

Schritt 1:  

füge die recaptcha Javascript API zu deiner index.html hinzu

index.html

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

Schritt 2:  

erstellen Sie eine Komponente mit dem Namen Recaptcha oder wie auch immer Sie sie nennen möchten (wenn Sie eine Komponente erstellen, wird der Code leichter lesbar, einfacher zu verwalten und das Recaptcha kann bei Bedarf mehr als einer Seite hinzugefügt werden.)

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>

Schritt 3:  

Importieren Sie die Recaptcha-Komponente und fügen Sie sie Ihrer Seite (übergeordnete Komponente) hinzu.

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

Ich benutze keine Komponente, aber ich hatte das gleiche Problem, und schließlich löse ich es so:

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

Das Problem, das ich mit den anderen Lösungen hatte, ist, dass es manchmal versucht, den window.grecaptcha.render Auszuführen, wenn ReCaptcha nicht vollständig geladen ist. Die einzige Möglichkeit, dies gemäß ihrer Dokumentation zu überprüfen, ist die Verwendung einer onload -Methode.

Dieses Beispiel unten ist, wie ich es verwendet habe, natürlich können Sie anpassen, was Sie mit dem Rückruf tun.

ReCaptcha.Vue:

<template>
    <div ref="grecaptcha"></div>
</template>

<script>
    export default {

        props: ['sitekey'],

        methods: {

            loaded(){

                window.grecaptcha.render(this.$refs.grecaptcha, {
                    sitekey: this.sitekey,
                    callback: (response) => {

                        this.$emit('input', response);

                    },
                });

            },

        },

        mounted(){

            /**
             * Set Recapchat loaded function
             */
            window.ReCaptchaLoaded = this.loaded;

            /**
             * Set Recaptcha script in header
             */
            var script = document.createElement('script');
            script.src = 'https://www.google.com/recaptcha/api.js?onload=ReCaptchaLoaded&render=explicit';
            document.head.appendChild(script);

        }

    }
</script>

Verwendung :

<ReCaptcha sitekey="KEY" v-model="fields.g_recaptcha_response.value" />
1
Stef Blokdijk

Wenn Sie nur nach dem Antwortwert von recaptcha suchen, um ihn auf Serverseite zu überprüfen, können Sie Ihr recaptcha-Element in eine Form setzen und den Antwortwert vom Zielelement des Submit event abrufen.

<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>

Und in checkForm Methode:

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

           ...
         }
1
Kasrâmvd
in Vue Component : 

in vorlage: html

<template>
<form @submit.prevent="onSubmit">
    <div class="form-group row">
        <label for="email" class="col-sm-4 col-form-label text-md-right">Email : </label>

        <div class="col-md-6">
            <input v-model="email" id="email"  type="email" class="form-control"  value="" required autofocus>


            <span class="invalid-feedback" role="alert">
                                    <strong></strong>
                                </span>

        </div>
    </div>

    <div class="form-group row">
        <label for="password" class="col-md-4 col-form-label text-md-right">
            Password :
        </label>

        <div class="col-md-6">
            <input v-model="password" id="password" type="password" class="form-control"  required>


            <span class="invalid-feedback" role="alert">
                                    <strong></strong>
                                </span>

        </div>
    </div>

    <div class="form-group row">
        <div class="col-md-6 offset-md-4">
            <div class="form-check">

                <input class="form-check-input" type="checkbox" id="remember" v-model="remember">

                <label class="form-check-label" for="remember">
                   Remember me
                </label>
                <div id="recaptcha" class="g-recaptcha" data-sitekey="6LehfpsUAAAAAIf3hvWNrGvat8o4lypZh_p6snRH"></div>
            </div>
        </div>
    </div>

    <div class="form-group row mb-0">
        <div class="col-md-8 offset-md-4">
            <a href="" class="btn btn-danger">Login with google</a>
            <button type="submit" class="btn btn-primary">
                Login
            </button>

            <a class="btn btn-link" href="">
                Forgot Your Password?
            </a>
        </div>
    </div>
</form>

und Javascript:

<script>
import swal from 'sweetalert';
export default {
   data(){

       return {
           email: '',
           password: '',
           remember: ''
       }

   },
    mounted: function() {
        this.initReCaptcha();
    },
    methods: {
        onSubmit(event) {

            let recaptcha_response_value = event.target['g-recaptcha-response'].value;
            console.log(recaptcha_response_value);
            let formData = new FormData();
            formData.append('email' , this.email);
            formData.append('password' , this.password);
            formData.append('remember' , this.remember);
            formData.append('g-recaptcha-response' , recaptcha_response_value);
            axios.post('/login' , formData)
                .then(
                    function(res){
                        swal('ورود شما موفقیت آمیز بود');
                    }
                )
                .catch(function(err){
                    swal('ایمیل یا کلمه عبور اشتباه است یا اینکه هنوز ثبت نام نکرده اید');
                    console.log(err);
                });

        }
    }

}
0
Hossein Shafiei