Ajax Project - Form CAPTCHA

Didn't find what you want? Try our search

You've probably seen the CAPTCHA technique used to prevent automatic form submission by spambots and other nuisances.

These operate by displaying an image containing a random string. These strings are very hard for computer programs to read, but straightforward for humans. The user must then enter the displayed string correctly in a form field in order to submit the form.

In many cases, the comparison of the two strings (displayed and entered) is carried out AFTER form submission. It would be nicer if it could be carried out BEFORE submission, using Ajax, as part of the normal form validation.

In this little project we do just that. Our form contains an image generated on-the-fly by a PHP routine using PHP's inbuilt GD graphics library.

Before reading through this tutorial, you'll need a little knowledge about the general architecture of Ajax applications. All the required information is in the pages of this site.

Here's the form, displaying the CAPTCHA image:

Required field:
Optional field:
Captcha image:
String:

Try completing the form with and without a correct string in the code field, and see what happens.

Here's the complete code for such a form, including the Ajax Javascript code:

<html> <head> <title>Ajax Captcha</title> <script language="JavaScript"> var url = 'captcheck.php?code='; var captchaOK = 2; // 2 - not yet checked, 1 - correct, 0 - failed function getHTTPObject() { try { req = new XMLHttpRequest(); } catch (err1) { try { req = new ActiveXObject("Msxml12.XMLHTTP"); } catch (err2) { try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch (err3) { req = false; } } } return req; } var http = getHTTPObject(); // We create the HTTP Object function handleHttpResponse() { if (http.readyState == 4) { captchaOK = http.responseText; if(captchaOK != 1) { alert('The entered code was not correct. Please try again'); document.myform.code.value=''; document.myform.code.focus(); return false; } document.myform.submit(); } } function checkcode(thecode) { http.open("GET", url + escape(thecode), true); http.onreadystatechange = handleHttpResponse; http.send(null); } function checkform() { // First the normal form validation if(document.myform.req.value=='') { alert('Please complete the "required" field'); document.myform.req.focus(); return false; } if(document.myform.code.value=='') { alert('Please enter the string from the displayed image'); document.myform.code.value=''; document.myform.code.focus(); return false; } // Now the Ajax CAPTCHA validation checkcode(document.myform.code.value); return false; } </script> </head> <body> <form action="landing.php" method="post" name="myform"> <table> <tr><td>Required field:</td> <td><input type="text" name="req" value=""></td></tr> <tr><td>Optional field:</td> <td><input type="text" name="opt" value=""></td></tr> <tr><td>Captcha image:</td> <td><img src="captcha.php" border="0"></td></tr> <tr><td>String:</td> <td><input type="text" name="code" value=""></td></tr> <tr><td></td> <td><input type="submit" value="Submit Form" onclick="return checkform()"></td> </tr> </table> </form> </body> </html>

See how the image is created by using a source file 'captcha.php'. We'll explain this script later on. Suffice to say, for now, that the script generates an image bearing a random character sequence, and stores that sequence in a PHP session variable.

Most of the remaining code will already be familiar to you, especially the function getHTTPObject() and the general style of the callback function handleHttpResponse(). (If not, please have a look at around this site for tutorials and example code).

The important part of this application is the function checkform(). This function handles the normal form validation routines, before calling our Ajax routine checkcode(). The code string entered by the user is then appended to the server URL as part of a parameter/value pair:

captcheck.php?code={user entered code}

Now let's consider what happens in the server script captcheck.php:

// continue the session so we can access the session variable session_start(); // Make posted code into upper case, then compare with the stored string if(strtoupper($_GET['code']) != $_SESSION['secret_string']) { echo '0'; // failed } else { echo '1'; // passed }

We use the PHP function strtoupper() to convert what our user has entered to upper case, thereby allowing the user to enter the string in a case-insensitive manner.

We then compare that string to the session variable containing the string (which is already in upper case) generated within the image. If they match, we return a 1 - otherwise a 0.

Our callback function handleHttpResponse() checks for this value, and applies it to variable captchaOK. We then check that variable 's value and, if we find a 1, we submit the form - otherwise, we output the error in a JavaScript alert, and return the user to the form.

Finally, let's turn to the image generation routine. For simplicity, we use an external file as the background, then simply generate the string using a random-generation routine, and add it in a TTF font.

We won't go into much detail over the GD commands here - see the PHP manual for details (after all, this is an Ajax tutorial site, not GD!). Hopefully the code comments should make it pretty clear what's happening though. Here's the code for captcha.php:

//Start a session so we can store the captcha code as a session variable. session_start(); // Decide what characters are allowed in our string // Our captcha will be case-insensitive, and we avoid some // characters like 'O' and 'l' that could confuse users $charlist = '23456789ABCDEFGHJKMNPQRSTVWXYZ'; // Trim string to desired number of characters - 5, say $chars = 5; $i = 0; while ($i < $chars) { $string .= substr($charlist, mt_rand(0, strlen($charlist)-1), 1); $i++; } // Create a GD image from our background image file $captcha = imagecreatefrompng('captcha.png'); // Set the colour for our text string // This is chosen to be hard for machines to read against the background, but // OK for humans $col = imagecolorallocate($captcha, 240, 200, 240); // Write the string on to the image using TTF fonts imagettftext($captcha, 17, 0, 13, 22, $col, 'Whimsy.TTF', $string); // Store the random string in a session variable $_SESSION['secret_string'] = $string; // Put out the image to the page header("Content-type: image/png"); imagepng($captcha);

Note that we need to include some files in the same folder as our form. These are the background image captcha.png, and the font file (here we have used Whimsy.TTF - but you can use any TTF font you like).

Please note that this is simplified code for study purposes and may need a little modification to work well in your own application.


Before using any software from this site, please see the Terms

2 Users Online.

All of the code and information on this site is provided free of charge (but without warranty).
If you feel that the site has been useful, you may care to donate a little toward the running of the site and the development of further projects?