jQuery Form CAPTCHA Code Example

  1. Client-side
  2. Server-side

I. Client-side

The jQuery Form Captcha code example shows how to add BotDetect CAPTCHA protection to a typical jQuery form.

Captcha validation is integrated with other form fields validation, and only submissions that meet all validation criteria are accepted.

This kind of validation could be used on various types of public forms which accept messages, and are at risk of unwanted automated submissions.

For example, it could be used to ensure bots can't submit anything to a contact form, add guestbook entries, blog post comments or anonymous message board / forum replies.

Download the BotDetect ASP.NET CAPTCHA Library and run this example

Installed Location

By default, the jQuery Basic CAPTCHA code example project is installed at:
C:\Program Files\Captcha Inc\BotDetect 4 CAPTCHA Component\Asp.Net\.NET\WebApp\SimpleAPI\jQueryCaptchaExample

You can also run it from the BotDetect Start Menu:
Programs > Captcha Inc > BotDetect 4 CAPTCHA Component > ASP.NET > ASP.NET Examples > Run .NET Examples

contact-captcha.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>BotDetect jQuery CAPTCHA Examples</title>
  <link href="styles/styles.css" type="text/css" rel="stylesheet">
</head>
<body>
  <header>
    <div class="header-content"><h1>BotDetect jQuery CAPTCHA Examples</h1></div>
  </header>

  <nav>
   <ul class="nav">
    <li><a href="basic-captcha.html">Basic Example</a></li>
    <li><a href="contact-captcha.html" class="active">Contact Example</a></li>
   </ul>
  </nav>

  <section id="main-content">
    <form id="contactForm" method="POST">
      <div id="form-messages"></div>

      <label>
        <span>Name:</span>
        <input type="text" id="name" name="name">
      </label>
      <div class="error name"></div>


      <label>
        <span>Email</span>
        <input type="email" id="email" name="email" >
      </label>
      <div class="error email"></div>


      <label>
        <span>Subject:</span>
        <input type="text" id="subject" name="subject">
      </label>
      <div class="error subject"></div>


      <label>
        <span>Message:</span>
        <textarea id="message" name="message"></textarea>
      </label>
      <div class="error message"></div>


      <!-- show Captcha image html-->
      <div id="botdetect-captcha" data-stylename="jqueryFormCaptcha"></div>

      <label>
        <span>Retype the characters from the picture:</span>
        <!-- captcha code user input textbox -->
        <input
          type="text"
          id="captchaCode"
          name="captchaCode"
          data-correct-captcha
        >
      </label>
      <div class="error captchaCode"></div>

      <button type="submit" id="submitButton" class="btn btn-primary">Send</button>
    </form>
  </section>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  <script src="node_modules/jquery-captcha/dist/jquery-captcha.min.js"></script>
  <script src="js/contact.js"></script>
</body>
</html>

Adding Captcha protection to the jQuery form is as simple as declaring an HTML element and set to data-stylename attribute a Captcha style name defined in botdetect.xml configuration file below.

In captcha code input element, we add data-correct-captcha attribute. It will tell BotDetect Captcha jQuery plugin to validate captcha code on blur event.

Beside the captcha code input field, the example form contains three other fields which are going to be validated in contact.js later.

At the bottom of the file, we do not forget to include the BotDetect Captcha jQuery plugin in your HTML template.

contact.js

$(function() {

  // load BotDetect Captcha, it requires you to configure 
  // BotDetect ASP.NET Captcha path to captchaEndpoint setting
  var captcha = $('#botdetect-captcha').captcha({
    captchaEndpoint: 'BotDetectCaptcha.ashx'
  });
  
  // error messages of input fields
  var errorMessages = {
    name: 'Name must be at least 3 characters.',
    email: 'Email is invalid.',
    subject: 'Subject must be at least 10 characters.',
    message: 'Message must be at least 10 characters.',
    captchaCode: 'Invalid code.'
  };
  
  // global variables that holds validation status of captcha input field, 
  // use them for checking validation status when form is submitted
  var isNameValid = false,
      isEmailValid = false,
      isSubjectValid = false,
      isMessageValid = false;
  
  
  function validateName() {
    var name = $('#name').val();
    isNameValid = (name.length >= 3);
    if (isNameValid) {
      $('.name').text('');
    } else {
      $('.name').text(errorMessages.name);
    }
  }
  
  function validateEmail() {
    var email = $('#email').val();
    var emailRegEx = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    isEmailValid = emailRegEx.test(email);
    if (isEmailValid) {
      $('.email').text('');
    } else {
      $('.email').text(errorMessages.email);
    }
  }
  
  function validateSubject() {
    var subject = $('#subject').val();
    isSubjectValid = (subject.length >= 10);
    if (isSubjectValid) {
      $('.subject').text('');
    } else {
      $('.subject').text(errorMessages.subject);
    }
  }
  
  function validateMessage() {
    var message = $('#message').val();
    isMessageValid = (message.length >= 10);
    if (isMessageValid) {
      $('.message').text('');
    } else {
      $('.message').text(errorMessages.message);
    }
  }
  
  // validate input fields on blur event
  $('#name').blur(validateName);
  $('#email').blur(validateEmail);
  $('#subject').blur(validateSubject);
  $('#message').blur(validateMessage);
  
  // UI captcha validation on blur event by using the custom 'validatecaptcha' event
  // and checking the 'isCorrect' variable to either show error messages 
  // or check captcha code input field status when form is submitted
  $('#captchaCode').on('validatecaptcha', function(event, isCorrect) {      
    // display or remove error message
    if (isCorrect) {
      $('.captchaCode').text('');
    } else {
      $('.captchaCode').text(errorMessages.captchaCode);
    }
  });

  
  // On contact form submit
  $('#contactForm').submit(function(event) {

    // use validateUnsafe() method to perform client-side captcha validation
    captcha.validateUnsafe(function(isCaptchaCodeValid) {

      if (isCaptchaCodeValid && isNameValid && isEmailValid && isSubjectValid && isMessageValid) {
        // form is valid
        // we send contact data as well as captcha data to server-side for
        // validating once again before they are inserted into database
        

        // captcha id for validating captcha at server-side
        var captchaId = captcha.getCaptchaId();

        // captcha code input value for validating captcha at server-side
        var captchaCode = captcha.getCaptchaCode();

        var postData = {
          name: $('#name').val(),
          email: $('#email').val(),
          subject: $('#subject').val(),
          message: $('#message').val(),
          captchaId: captchaId,
          captchaCode: captchaCode
        };
        
        $.ajax({
          method: 'POST',
          url: 'form/ContactHandler.ashx',
          data: JSON.stringify(postData),
          success: function(response) {
            if (response.success) {
              // captcha, other form data passed and the data is also stored in database
              // show success message
              $('#form-messages')
                .removeClass()
                .addClass('alert alert-success')
                .text('Your message was sent successfully!');
            } else {
              // form validation failed
              $('#form-messages')
                .removeClass()      
                .addClass('alert alert-error')
                .text('An error occurred while sending your message, please try again.');
            }
          },
          complete: function() {
            // always reload captcha image after validating captcha at server-side 
            // in order to update new captcha code for current captcha id
            captcha.reloadImage();
          },
          error: function(error) {
            throw new Error(error);
          }
        });
        
      } else {
        // form is invalid
        $('#form-messages')
          .removeClass()      
          .addClass('alert alert-error')
          .text('Please enter valid values.');
      } 

    });

    event.preventDefault();
  });
  
});

We first load BotDetect Captcha jQuery plugin, it requires you to configure a BotDetect ASP.NET Captcha path to captchaEndpoint setting.

Once we add data-correct-captcha attribute in the captcha code input element, BotDetect Captcha jQuery plugin will then automatically validate captcha code on blue event in default. And to check the UI captcha validation result, we listen the custom validatecaptcha event, which will be fired on captcha code input blur event.

We also define validation functions and perform blur validation for other contact fields.

On form submit, after the form is valid we need to send captcha id value and captcha code visitors submitted to server-side to validate Captcha code once at server-side api. Once request finished, we always reload Captcha by calling reloadImage() function of captcha object. This is needed to generate the new captcha code for the current captcha id.

II. Server-side

botdetect.xml

<?xml version="1.0" encoding="UTF-8"?>
<botdetect xmlns="https://captcha.com/schema/net"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://captcha.com/schema/net 
     https://captcha.com/schema/net/botdetect-4.4.0.xsd">

  <captchaStyles>
    <captchaStyle>
      <name>jqueryFormCaptcha</name>
      <userInputID>captchaCode</userInputID>
      <codeLength>4-6</codeLength>
      <codeStyle>Alphanumeric</codeStyle>
    </captchaStyle>
  </captchaStyles>

</botdetect>

In botdetect.xml, we configure some captcha options for our jquery form captcha. You can find a full list of available SimpleCaptcha configuration options and related instructions at the SimpleCaptcha configuration options page.

ContactHandler.ashx

<%@ WebHandler Language="C#" Class="ContactHandler" %>

using System;
using System.Web;
using System.IO;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using BotDetect.Web;


public class ContactHandler : IHttpHandler
{

    public void ProcessRequest (HttpContext context)
    {

        if (HttpContext.Current.Request.HttpMethod == "POST")
        {
            string dataJson = new StreamReader(context.Request.InputStream).ReadToEnd();

            Dictionary<string, string> formDataObj = new Dictionary<string, string>();
            formDataObj = JsonConvert.DeserializeObject<Dictionary<string, string>>(dataJson);

            string name = formDataObj["name"];
            string email = formDataObj["email"];
            string subject = formDataObj["subject"];
            string message = formDataObj["message"];

            string captchaId = formDataObj["captchaId"];
            string captchaCode = formDataObj["captchaCode"];

            // validate captcha
            Dictionary<string, string> errors = new Dictionary<string, string>();

            if (!IsValidName(name))
            {
                errors.Add("name", "Name must be at least 3 characters.");
            }

            if (!IsValidEmail(email))
            {
                errors.Add("email", "Email is invalid.");
            }

            if (!IsValidSubject(subject))
            {
                errors.Add("subject", "Subject must be at least 10 characters.");
            }

            if (!IsValidMessage(message))
            {
                errors.Add("message", "Message must be at least 10 characters.");
            }

            if (!IsCaptchaCorrect(captchaCode, captchaId))
            {
                errors.Add("captchaCode", "CAPTCHA validation failed.");
            }


            bool isErrorsEmpty = errors.Count > 0 ? false : true;

            if (isErrorsEmpty)
            {
                // everything is ok
                // TODO: Insert form data into your database
            }

            // the object that stores validation result
            Dictionary<string, object> validationResult = new Dictionary<string, object>();
            validationResult.Add("success", isErrorsEmpty);
            validationResult.Add("errors", errors);

            // write the validation result as json string for sending it back to client
            context.Response.ContentType = "application/json; charset=utf-8";
            context.Response.Write(JsonConvert.SerializeObject(validationResult));
        }
    }

    // validate function
    private bool IsCaptchaCorrect(string captchaCode, string captchaId)
    {
        SimpleCaptcha captcha = new SimpleCaptcha();
        return captcha.Validate(captchaCode, captchaId);
    }

    private bool IsValidName(string name)
    {
        if (name == null)
        {
            return false;
        }

        return (name.Length >= 3);
    }

    private bool IsValidEmail(string email)
    {
        if (email == null)
        {
            return false;
        }
        Regex regex = new Regex("^[\w-_\.+]*[\w-_\.]\@([\w]+\.)+[\w]+[\w]$");
        Match match = regex.Match(email);

        return match.Success;
    }

    private bool IsValidSubject(string subject)
    {
        if (subject == null)
        {
            return false;
        }

        return (subject.Length > 9) && (subject.Length < 255);
    }

    private bool IsValidMessage(string message)
    {
        if (message == null)
        {
            return false;
        }

        return (message.Length > 9) && (message.Length < 255);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}

At server-side api, we will get captchaId and captchaCode values sent from client-side and use Validate(captchaCode, captchaId) method of SimpleCaptcha instance to validate Captcha code. Finally, we write the validation result as json string for sending it back to client.


Please Note

jQuery Captcha Plugin requires the new experimental Simple API that is currently available in BotDetect Java v4.0.Beta3+, BotDetect PHP v4.2.0+, as well as in BotDetect ASP.NET v4.4.0 build for legacy .NET.
The Simple API for ASP.NET Core will be available in the BotDetect ASP.NET v4.4.1 that will be released in few weeks time.