ReCaptcha 2.0 With AJAX

JavascriptPhpJqueryAjaxRecaptcha

Javascript Problem Overview


I have managed to get ReCaptcha 2.0 working in my website. However, it's only working when I don't use AJAX and I let the form submit "naturally".

I want to submit the form with the captcha and alert the user with a success note without refreshing the page.

I tried the following code, but it seems like the server doesn't get the user response:

HTML:

<form class="form" action="javascript:void(0)" novalidate>
    <!-- all the inputs... -->
 
	<!-- captcha -->
	<div class="input-group">
		<div class="g-recaptcha" data-sitekey="6LdOPgYTAAAAAE3ltWQGar80KUavaR-JblgPZjDI"></div>
	</div>
 
	<div class="errors" id="errors" style="display: none"></div>
 
	<div class="input-group">
		<input type="button" value="Send" class="btn-default right" id="submit">
		<div class="clear"></div>
	</div>
</form>

JS:

$('#submit').click(function(e) {
	console.log('clicked submit'); // --> works

	var $errors = $('#errors'),
		$status = $('#status'),

		name = $('#name').val().replace(/<|>/g, ""), // prevent xss
		email = $('#email').val().replace(/<|>/g, ""),
		msg = $('#message').val().replace(/<|>/g, "");

	if (name == '' || email == '' || msg == '') {
		valid = false;
		errors = "All fields are required.";
	}

    // pretty sure the problem is here
	console.log('captcha response: ' + grecaptcha.getResponse()); // --> captcha response: 

	if (!errors) {
		// hide the errors
		$errors.slideUp();
		// ajax to the php file to send the mail
		$.ajax({
			type: "POST",
			url: "http://orenurbach.com/assets/sendmail.php",
			data: "email=" + email + "&name=" + name + "&msg=" + msg + "&g-recaptcha-response=" + grecaptcha.getResponse()
		}).done(function(status) {
			if (status == "ok") {
				// slide down the "ok" message to the user
				$status.text('Thanks! Your message has been sent, and I will contact you soon.');
				$status.slideDown();
				// clear the form fields
				$('#name').val('');
				$('#email').val('');
				$('#message').val('');
			}
		});
	} else {
		$errors.text(errors);
		$errors.slideDown();
	}
});

PHP:

<?php
    // assemble the message from the POST fields

	// getting the captcha
	$captcha = '';
	if (isset($_POST['g-recaptcha-response']))
		$captcha = $_POST['g-recaptcha-response'];
	echo 'captcha: '.$captcha;

	if (!$captcha)
		echo 'The captcha has not been checked.';
	// handling the captcha and checking if it's ok
	$secret = 'MY_SECRET';
	$response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']), true);

	var_dump($response);

	// if the captcha is cleared with google, send the mail and echo ok.
	if ($response['success'] != false) {
		// send the actual mail
		@mail($email_to, $subject, $finalMsg);

		// the echo goes back to the ajax, so the user can know if everything is ok
		echo 'ok';
	} else {
		echo 'not ok';
	}
?>

The result in the PHP page:

captcha: The captcha has not been checked.array(2) { ["success"]=> bool(false) ["error-codes"]=> array(1) { [0]=> string(22) "missing-input-response" } } not ok

Bottom line is, how can I get the input response manually without it automatically going with the rest of the POST data?

Javascript Solutions


Solution 1 - Javascript

Ok, this was pretty silly.

I have done a couple of things wrong:

  • In the PHP file, all the strings had single quotes on them, and that caused problems.

  • Throughout the testing, I added multiple printings of things in the PHP file, thus the if (status == "ok") was never working. I did get the emails but did not get any conformation that I did and now I see why.

  • When I wanted to check what the PHP file was omitting, I simply went to it's address in the URL and always got an error. Even when the mails were sent. Now I understand that that is not the correct way of checking the logs.

Thanks to @Samurai who helped my figure out things.


Final PHP code:

<?php
    // assemble the message from the POST fields

    // getting the captcha
    $captcha = "";
    if (isset($_POST["g-recaptcha-response"]))
        $captcha = $_POST["g-recaptcha-response"];

    if (!$captcha)
        echo "not ok";
    // handling the captcha and checking if it's ok
    $secret = "MY_SECRET";
    $response = json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$captcha."&remoteip=".$_SERVER["REMOTE_ADDR"]), true);

    // if the captcha is cleared with google, send the mail and echo ok.
    if ($response["success"] != false) {
        // send the actual mail
        @mail($email_to, $subject, $finalMsg);

        // the echo goes back to the ajax, so the user can know if everything is ok
        echo "ok";
    } else {
        echo "not ok";
    }
?>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGofilordView Question on Stackoverflow
Solution 1 - JavascriptGofilordView Answer on Stackoverflow