Vue.js Google ReCaptcha callback

I am trying to get a recaptcha callback working with vue.js in a component. The captcha itself works, but not the callback that I define in the data-callback attribute.

I tried everything I could think of, but I still get that ReCAPTCHA couldn't find user-provided function: dothisthat .

Here is this component

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

None of the dothisthat functions are dothisthat . What am I doing wrong?

+13
javascript recaptcha
source share
4 answers

I also ran into this problem and it took me 2 days to solve this problem.

So, I will provide a general answer for integrating recaptcha with vue.js from scratch step by step, to be an easy guide for people who will be in the same situation in the future (I assume vue-cli is used here).

Note: I am using an invisible recaptcha here, but the process is pretty similar to normal

Step 1:

add recaptcha javascript api to your index.html

index.html

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

Step 2:

create a component called Recaptcha or whatever you want to call it (creating a component will make it easier to read the code, make it easier, and make it easier to add recaptcha to more than one page if you need to)

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> 

Step 3:

Import the recaptcha component and add it to your page (parent component).

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

I do not use the component, but I had the same problem, and finally I resolve it as follows:

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

If you are looking only for the value of the recaptcha response to test it on the server side, a simple solution is to put your recaptcha element in the form and get the response value from the target event submit element.

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

And in the checkForm method:

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

The problem I encountered in other solutions is that it sometimes tries to execute window.grecaptcha.render when window.grecaptcha.render not fully loaded. The only way to check this according to their documentation is to use the onload method.

This example is below, as I used it, of course, you can customize what you do with the callback.

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> 

Usage :

 <ReCaptcha sitekey="KEY" v-model="fields.g_recaptcha_response.value" /> 
0
source share

All Articles