"Not a robot" recaptcha without a <form> but AJAX instead

12,688

Solution 1

You use a form, interrupt the submissions of the form. Set up a form as per normal:

<form action="post.php" method="POST" id="my-form">
    <div class="g-recaptcha" data-sitekey="6Lc_0f4SAAAAAF9ZA_d7Dxi9qRbPMMNW-tLSvhe6"></div>
    <input type="text" id="text">
    <button type="submit">Sign in</button>
</form>

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

And then you use jQuery to interrupt the submission of the form and serialize it, allowing you to pass the data through Ajax:

$('#my-form').submit(function(e) {
    e.preventDefault();
    $this = $(this);
    $.ajax({
        type: "POST",
        url: "post.php",
        data: $this.serialize()
    }).done(function(data) {
    }).fail(function( jqXHR, textStatus ) {
        alert( "Request failed: " + textStatus );
    });
});

As you will have noticed I've used .done and .fail instead of success and error, this is the preferred way of handling the response.

Solution 2

I just implemented it without using any form and submit mechanism, respectively. Thus, a pure AJAX solution.

HTML code:

<div id="recaptcha-service" class="g-recaptcha"
 data-callback="recaptchaCallback"
 data-sitekey=""></div>
<script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=en"></script>

JavaScript code:

window.recaptchaCallback = undefined;

jQuery(document).ready(function($) {

  window.recaptchaCallback = function recaptchaCallback(response) {
    $.ajax({
      method: "POST",
      url: "http://example.com/service.ajax.php",
      data: { 'g-recaptcha-response': response },
    })
      .done(function(msg) {
        console.log(msg);
      })
      .fail(function(jqXHR, textStatus) {
        console.log(textStatus);
      });
  }

});

The point is using a callback (recaptchaCallback in this case).

You can find a more complete example at https://gist.github.com/martinburger/f9f37770c655c25d5f7b179278815084. That example uses Google's PHP implementation on the server side (https://github.com/google/recaptcha).

Solution 3

For answer completeness, say you wanted to just use a link you could...

<form id="g-recap">
  <div class="g-recaptcha" data-sitekey="{{ gcaptcha key }}" ></div>
</form>
<a href="/recaptchaured/path">Verify</a>

$('a').on('click',function(e) {
   e.preventDefault();
   document.location =  $(this).attr('href') + '?' + $('#g-recap').serialize()
});
Share:
12,688
Basj
Author by

Basj

I work on R&amp;D involving Python, maths, machine learning, deep learning, data science, product design, and MacGyver solutions to complex problems. I love prototyping, building proofs-of-concept. For consulting/freelancing inquiries : [email protected]

Updated on June 07, 2022

Comments

  • Basj
    Basj almost 2 years

    The traditional way of using "I am not a robot" Recpatcha seems to be with a <form> on client-side:

    <form action="post.php" method="POST">
        <div class="g-recaptcha" data-sitekey="6Lc_0f4SAAAAAF9ZA_d7Dxi9qRbPMMNW-tLSvhe6"></div>
        <button type="submit">Sign in</button>
    </form>
    
    <script src='https://www.google.com/recaptcha/api.js'></script>
    

    Then some g-recaptcha-response will be sent to server.


    However, in my code I don't use a <form> but an AJAX call instead:

    $('#btn-post').click(function(e) { 
      $.ajax({
        type: "POST",
        url: "post.php",
        data: {
          action: 'post',
          text: $("#text").val(),
          ajaxMode: "true"
        },
        success: function(data) { },
        error: function(data) { } 
      }); } });
    

    How to get the g-recaptcha-response answer with this solution?

  • Basj
    Basj almost 9 years
    So in order to not use a <form>, I should use a <form> ?
  • Styphon
    Styphon almost 9 years
    Yes. Even if you're submitting a form via Ajax, you still use a form and just interrupt the submission of the form and pass it off to Ajax. Give me a sec, I'm adding an example to my answer.
  • Basj
    Basj almost 9 years
    Ok. Is this a hack or normal way of doing it? Oh yes, I would be interested for an example code :)
  • Basj
    Basj almost 9 years
    something like $('#myForm').on('submit', function(e) { e.preventDefault(); $.ajax({ ..., data: $(this).serialize(), ... }); } ); ?
  • Styphon
    Styphon almost 9 years
    I've updated my answer, and yes this is the standard way of doing things.
  • HaukurHaf
    HaukurHaf almost 9 years
    It's called progressive enhancement. Start with the basic functionality and then add extended functionality for those who support it. If someone has JS disabled, the captcha should still work, since it will basically just fall back to the normal, good old fashioned form :-)
  • TechDogLover OR kiaNasirzadeh
    TechDogLover OR kiaNasirzadeh almost 6 years
    thank you very much, it works for me and it is a tremendously creative way but I just didn't realize why it is working!??? I did the exactly the same things just without using data-callback and relative statements and it didn't work, can you explain why we should use data-callback and ...?