Invisible recaptcha vs visible recaptcha | Community
Skip to main content
Grégoire_Miche2
Level 10
March 19, 2018
Question

Invisible recaptcha vs visible recaptcha

  • March 19, 2018
  • 2 replies
  • 9194 views

When implement an invisible recaptcha following the method described by @Sanford Whiteman​ here, the

var recaptchaResponse = grecaptcha.getResponse();

returns an empty response, and the validation fails.

this is the complete code used:

  In the <head>

<meta class="mktoBoolean" id="GoogleRecaptcha" mktoName="Google Recaptcha" default="false" true_value="true" false_value="false" false_value_name="Deactivated" true_value_name="Activated">

in the <body>

<div id="InvisibleRecaptcha" class="g-recaptcha" data-sitekey="${GoogleRecaptchaSiteKey}" data-size="invisible" data-callback="donothing"></div>

in the forms whenready:

var formEl = form.getFormElem()[0],

  emailEl = formEl.querySelector('#Email'),

  submitEl = formEl.querySelector('BUTTON[type="submit"]'),

  recaptchaEl = document.querySelector('.g-recaptcha’),

  formElId = form.getId();

if (${GoogleRecaptcha}) {

  form.submittable(false);

  // force resize reCAPTCHA frame

  recaptchaEl.querySelector('IFRAME').setAttribute('height','140');

  // move reCAPTCHA inside form container   

  formEl.appendChild(recaptchaEl);

}

 

form.onValidate(function(builtInValidation){       

  //code to handle the recaptcha

  if(${GoogleRecaptcha}) {

    if (!builtInValidation) return;

           

    //calling the recaptcha

      var recaptchaResponse = grecaptcha.getResponse();

      if (!recaptchaResponse) {

        recaptchaEl.classList.add('mktoInvalid');

      } else {

        recaptchaEl.classList.remove('mktoInvalid');

        form.addHiddenFields({

          lastRecaptchaUserInput: recaptchaResponse,

          lastRecaptchaEnabledFormID: formElId

        });

        form.submittable(true);

      }

    }     

});

Any idea about what I am missing?

The same code works perfectly well with a visible (v2) recaptcha.

-Greg

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

2 replies

SanfordWhiteman
Level 10
March 20, 2018

What's the URL?

Grégoire_Miche2
Level 10
March 20, 2018

Hi Sanford

Here it is. And thx

-Greg

SanfordWhiteman
Level 10
March 20, 2018

The invisible form doesn't have an internal IFRAME (and doesn't need to be moved), so you need to take out these lines:

recaptchaEl.querySelector('IFRAME').setAttribute('height','140'); 

formEl.appendChild(recaptchaEl); 

Level 2
April 17, 2018

Hi Greg,

You'll need to use...

grecaptcha.execute(reCAPTCHA);

...when someone tries to submit the form. If you don't programmatically "execute" the Invisible reCAPTCHA...

grecaptcha.getResponse();

...will always return an empty response. (Invisible) reCAPTCHA uses a callback that you should use to handle completion of the captcha after executing it. Also, if you want to support multiple forms on the same page, you'll have to create multiple instances of reCAPTCHA (for each form) and should thus not include the following HTML as described in the documentation.

<div class="g-recaptcha"
    
data-sitekey="your_site_key"
    
data-callback="onSubmit"
    
data-size="invisible">
</div>

Instead, just include the reCAPTCHA script on your page and embed the forms as you would do normally.

<script src='https://www.google.com/recaptcha/api.js?render=explicit'></script>

<script src="https://app-lon07.marketo.com/js/forms2/js/forms2.min.js"></script>

<form id="mktoForm_1"></form>

<script>MktoForms2.loadForm("//app-lon07.marketo.com", "123-ABC-456", 1);</script>

Then use the following script to use it for all forms. If needed you can also slightly adjust it to only use reCAPTCHA for one or a couple of forms.

/**

* Use Google's reCAPTCHA to protect against spam and other types of automated abuse.

* @param {Object} mktoForm

* @param {Object} options

* @param {String} options.size 'invisible', 'compact', 'normal'

* @param {String} options.siteKey Public reCAPTCHA sitekey

* @param {String} options.fieldName Marketo SOAP name for field that holds response value

* @param {String} options.errorMessage Error message depending on choosen `size`

* @return {Void}

*/

function useReCAPTCHA(mktoForm) {

  var options =

    arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  if (

    !Object.prototype.hasOwnProperty.call(options, "fieldName") ||

    !Object.prototype.hasOwnProperty.call(options, "sitekey") ||

    !Object.prototype.hasOwnProperty.call(options, "errorMessage") ||

    !Object.prototype.hasOwnProperty.call(options, "size")

  ) {

    if (console) {

      console.warn("Parameters for reCAPTCHA are missing.");

    }

    return;

  }

  var formEl = mktoForm.getFormElem()[0];

  var formId = mktoForm.getId();

  var reCAPTCHAEl = document.createElement("div");

  reCAPTCHAEl.setAttribute("id", "reCAPTCHA_" + formId);

  formEl.parentNode.insertBefore(reCAPTCHAEl, formEl.nextSibling);

  var reCAPTCHA = grecaptcha.render("reCAPTCHA_" + formId, {

    size: options.size,

    sitekey: options.sitekey,

    callback: function callback() {

      mktoForm.submittable(true);

      mktoForm.submit();

    },

    "error-callback": function errorCallback() {

      mktoForm.showErrorMessage(options.errorMessage);

    }

  });

  mktoForm.onValidate(function(isValid) {

    if (!isValid || !mktoForm.submittable()) {

      return;

    }

    var reCAPTCHAResponse = grecaptcha.getResponse(reCAPTCHA);

    if (!reCAPTCHAResponse) {

      if (options.size === 'invisible') {

        grecaptcha.execute(reCAPTCHA);

      } else {

        mktoForm.showErrorMessage(options.errorMessage);

      }

      mktoForm.submittable(false);

    } else {

      var hiddenFields = {};

      hiddenFields[options.fieldName] = reCAPTCHAResponse;

      mktoForm.addHiddenFields(hiddenFields);

    }

  });

}

MktoForms2.whenReady(function(mktoForm) {

  useReCAPTCHA(mktoForm, {

    size: "invisible",

    sitekey: "KEY",

    fieldName: "lastreCAPTCHAResponse",

    errorMessage: "Sorry, something wen't wrong"

  });

});

Please note that I haven't tested it fully (yet) but feel free to test if it works for you. It did for me in my tests.

Best regards,
Markus