ASP Classic jQuery Validation CAPTCHA VBScript Code Sample (BotDetect v3.0; deprecated)

This code sample shows how to integrate BotDetect ASP Classic Captcha validation with jQuery Validation client-side form validation.

First Time Here?

Check the BotDetect Developer Crash Course for key integration steps.

Client-side validation is not secure by itself (it can be bypassed trivially by bots that don't execute JavaScript at all), so the sample shows how the protected form action must always be secured by server-side Captcha validation first, and uses client-side validation only to improve the user experience.

Installed Location

By default, the Classic ASP jQuery Validation Captcha code sample is installed at:
C:\Program Files\Lanapsoft\BotDetect 3 CAPTCHA Component\Asp\WebApp\AspJQueryValidationCaptchaSample

You can also run it from the BotDetect Start Menu:
Programs > Lanapsoft > BotDetect 3 CAPTCHA Component > ASP > Web Applications > Run

Default.asp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
  <title>BotDetect CAPTCHA ASP jQuery Validation Sample</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <!-- #include file ="BotDetect.asp" -->
  <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
  <script type="text/javascript" src="js/jquery.validate.min.js"></script>
</head>
<body>
  <form method="post" action="ProcessForm.asp" id="form1">

    <h1>BotDetect CAPTCHA ASP jQuery Validation Sample</h1>

    <h2>Add Message</h2>

    <fieldset>
      <legend>CAPTCHA included in ASP form validation</legend>

      <div class="input">
        <label for="Name">Name:</label>
        <input type="text" name="Name" id="Name" class="textbox"
        value="<%=Request("Name") %>" />
        <% ' name validation failed, show error message
        If Request("nameValid") = "False" Then %>
          <label class="incorrect">*</label><%
        End If
      %>
      </div>

      <div class="input">
        <label for="Email">Email:</label>
        <input type="text" name="Email" id="Email" class="textbox"
        value="<%=Request("Email") %>" />
        <% ' email validation failed, show error message
        If Request("emailValid") = "False" Then %>
          <label class="incorrect">*</label><%
        End If
      %>
      </div>

      <div class="input">
        <label for="Message">Short message:</label>
        <textarea class="inputbox" id="Message" name="Message"
        rows="5" cols="40"><%=Request("Message") %></textarea>
       <% ' message validation failed, show error message
        If Request("messageValid") = "False" Then %>
          <label class="incorrect">*</label><%
        End If
      %>
      </div>

      <div class="input">
         <div class="input">
        <% ' Adding BotDetect CAPTCHA to the page 
          Dim FormCaptcha : Set FormCaptcha = (New Captcha)("FormCaptcha")
          FormCaptcha.UserInputID = "CaptchaCode"

          If Not FormCaptcha.IsSolved Then %>
            <label for="CaptchaCode">Retype the characters from the
            picture:</label>
            <%=FormCaptcha.Html %>
            <input type="text" name="CaptchaCode" id="CaptchaCode"
            class="textbox" /><%
            ' CAPTCHA validation failed, show error message
            If Request("captchaValid") = "False" Then %>
              <label class="incorrect">*</label><%
            End If
          End If
        %>
      </div>
      <input type="submit" name="SubmitButton" id="SubmitButton"
      value="Submit"  />
    </fieldset>

    <br />

    <p class="navigation"><a href="Messages.asp">View Messages</a></p>

    <script type="text/javascript" src="js/validationRules.js"></script>

  </form>
</body>
</html>

The input form code is almost exactly the same as in the form Captcha sample. The only differences are that we use label elements instead of spans for error message display, and that we must include jQuery, the jQuery.validate plugin, and the script containing our custom validation rules. To make the sample work in IE 6, we have to load the jQuery includes before Captcha markup.

js\validationRules.js

$(document).ready(function() {
  $("#form1").validate({
    rules: {
      Name: { required: true, minlength: 3 },
      Email: { required: true, email: true },
      Message: { required: true, minlength: 10 },
      // Captcha code is a required input, and its value is validated remotely
      // the remote validation Url is exposed through the BotDetect client-side
      // API
      CaptchaCode: {
        required: true,
        remote: $("#CaptchaCode").get(0).Captcha.ValidationUrl 
      }
    },
    messages: {
      Name: {
        required: "A name is required",
        minlength: jQuery.format("Enter at least {0} characters")
      },
      Email: {
        required: "An email address is required",
        email: "Please enter a valid email address"
      },
      Message: {
        required: "A message is required",
        minlength: jQuery.format("Enter at least {0} characters")
      },
      // error messages for Captcha code validation 
      CaptchaCode: {
        required: "The Captcha code is required",
        remote: "The Captcha code must be retyped correctly"
      }
    },
     // the Captcha input must only be validated when the whole code string is
    // typed in, not after each individual character (onkeyup must be false)
    onkeyup: false,
    // validate user input when the element loses focus
    onfocusout: function(element) { $(element).valid(); },
    // reload the Captcha image if remote validation failed
    showErrors: function(errorMap, errorList) {
      this.defaultShowErrors();
      if (typeof(errorMap.CaptchaCode) != "undefined" &&
          errorMap.CaptchaCode === this.settings.messages.CaptchaCode.remote) {
        $("#CaptchaCode").get(0).Captcha.ReloadImage();
      }
    },
    success: function(label) {
      label.text("Ok!");
      label.addClass(this.validClass);
    },
    errorClass: "incorrect",
    validClass: "correct",
    errorElement: "label"
  });
});

To set up jQuery validation of a textbox taking Captcha code input, we do the following:

  • Add validation rules specifying it as a required field, that also needs to be validated remotely when a value is entered; define error messages shown when these validation rules are triggered
  • Disable onkeyup validation of the Captcha code, since we must validate the whole code and not the individual characters
  • Reload the Captcha image whenever remote Captcha validation fails

CAPTCHA jQuery Validation Rules and Error Messages

We add the needed declarations in the rules and messages properties of the validation specification, tied to the Id of the Captcha code input element.

The expression for the remote Captcha validation Url can easily be read looking at dot-separated segments from right to left:

  • The ValidationUrl property is part of the BotDetect client-side API, and is unique for each Captcha instance.
  • The client-side BotDetect object can always be accessed through the Captcha property of the Captcha code textbox. For this custom property to be assigned, the textbox must be registered during server-side Captcha object initialization, through the UserInputID property (as has been done in Default.asp code above).
  • We use the standard jQuery selector to access the textbox by Id, and the .get(0) function call to get the underlying DOM element. This is needed because BotDetect adds the custom Captcha property to the DOM element directly, and the jQuery wrapper element returned by the jQuery selector doesn't include it.

Disabling Remote CAPTCHA Validation on Individual Character Input

Since BotDetect deletes the Captcha code stored on the server after failed validation of a particular Captcha instance (as explained in the BotDetect FAQ), we must avoid validating the user input before the user finished typing in the whole Captcha code. The simplest way to achieve this is to disable onkeyup validation completely (onkeyup: false).

Reloading the CAPTCHA Image When Remote Validation Fails

Due to the above (failed validation invalidates the stored code for security purposes), we must also always reload the Captcha image when remote validation fails. Otherwise the user would be trying to correct his input based on an expired image, and couldn't pass Captcha validation at all.

We do this by customizing the jQuery.validate showErrors callback: beside the regular functionality (this.defaultShowErrors), we also check that there is a Captcha validation error (typeof(errorMap.CaptchaCode) != "undefined") and that the error message indicates a remote validation failure (errorMap.CaptchaCode === this.settings.messages.CaptchaCode.remote). If that is case, we call the ReloadImage() function on the client-side Captcha object (accessed as explained above).

ProcessForm.asp

<!-- #include file ="BotDetect.asp" -->
<%
  Dim form_page : form_page = "Default.asp"
  Dim view_page : view_page = "Messages.asp"

  'directly accessing this script is an error
  If Not Request.ServerVariables("REQUEST_METHOD") = "POST" Then
    Response.Redirect form_page
  End If

  ' submitted data
  Dim name : name = Request("name")
  Dim email : email = Request("email")
  Dim message : message = Request("message")
  form_page = form_page & "?name=" & Server.URLEncode(name) &
  "&email=" & Server.URLEncode(email) & "&message=" & Server.URLEncode(
  message)

  ' total form validation result
  Dim isPageValid : isPageValid = True

  ' Captcha validation 
  Dim FormCaptcha : Set FormCaptcha = (New Captcha)("FormCaptcha")
  FormCaptcha.UserInputID = "CaptchaCode"
  If Not FormCaptcha.IsSolved Then
    Dim isHuman : isHuman = FormCaptcha.Validate()
    isPageValid = isPageValid And isHuman
    form_page = form_page & "&captchaValid=" & isHuman
  End If

  ' name validation
  Dim isNameValid : isNameValid = ValidateName(name)
  isPageValid = isPageValid And isNameValid
  form_page = form_page & "&nameValid=" & isNameValid

  ' email validation
  Dim isEmailValid : isEmailValid = ValidateEmail(email)
  isPageValid = isPageValid And isEmailValid
  form_page = form_page & "&emailValid=" & isEmailValid

  ' message validation
  Dim isMessageValid : isMessageValid = ValidateMessage(Message)
  isPageValid = isPageValid And isMessageValid
  form_page = form_page & "&messageValid=" & isMessageValid

  If Not isPageValid Then
    ' form validation failed, show error message
    Response.Redirect form_page
  End If

  ' keep a collection of submitted valid messages in Application state
  Call SaveMessage(name, message)
  Call FormCaptcha.Reset
  Response.Redirect view_page

  ' name validation
  Function ValidateName(name)
    Dim result : result = False
    If (Len(name) > 2 And Len(name) < 30) Then
      result = True
    End If
    ValidateName = result
  End Function

  ' email validaton
  Function ValidateEmail(email)
    Dim result : result = False
    If (Len(email) < 5 Or Len(email) > 100) Then
      result = False
    Else
      Dim regEx : Set regEx = New RegExp
      regEx.Pattern = "^(.+)@(.+)\.(.+)$"
      result = regEx.Test(email)
    End If
    ValidateEmail = result
  End Function

  ' message
  Function ValidateMessage(message)
    Dim result : result = False
    If (Len(message) > 2 And Len(message) < 255) Then
      result = True
    End If
    ValidateMessage = result
  End Function

  ' data storage
  Sub SaveMessage(name, email, message)
    ' we want to keep the sample code simple, so we'll store the 
    messages in Application state despite it being unfit for real-
    world use in such scenarios;
    ' using a database or another appropriate persistence medium would 
    complicate the sample code
    Application.Lock
    Application("Message_" & FormCaptcha.InstanceID) = Server.
    HTMLEncode(name) & " (" & Server.HTMLEncode(email) & ") says: " &
    Server.HTMLEncode(message)
    Application.UnLock
  End Sub

%>

Form submission validation is performed in this file, which checks all required fields and redirects the user back to the form if validation fails. Captcha validation is treated no different than other field validation. Server-side validation code is kept exactly the same as in the form Captcha sample.

We left the server-side Captcha validation (implemented in the form Captcha sample) in place, ensuring that any bots or users with JavaScript disabled have their input checked. For users with JavaScript enabled, errors in Captcha code input will be shown on the client without full form being POSTed to the server.

Messages.asp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
  <title>BotDetect CAPTCHA ASP jQuery Validation Sample</title>
  <link type="text/css" rel="Stylesheet" href="StyleSheet.css" />
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>

  <h1>BotDetect CAPTCHA ASP jQuery Validation Sample</h1>

  <h2>View Messages</h2>

  <%
   Dim count : count = 0
    For Each val In Application.Contents
      If InStr(val, "Message_") And Application(val) <> "" Then
        Response.Write "<p class=""message"">" & Application(val) & "<
        /p>"
        count = count + 1
      End If
    Next

    If count = 0 Then
      Response.Write "<p class=""message"">No messages yet.</p>"
    End If
  %>

  <br />

  <p class="navigation"><a href="Default.asp">Add Message</a></p>

</body>
</html>

This page displays all successfully submitted messages, and the user is automatically redirected here after validation of all form fields (including Captcha) is passed.

BotDetect\CaptchaConfig.asp

<%

' Captcha code configuration
' ---------------------------------------------------------------------
LBD_Configuration_CodeLength = 3
LBD_Configuration_CodeStyle = LBD_CodeStyles("Alphanumeric")
LBD_Configuration_CodeTimeout = 1200
LBD_Configuration_Locale = "en-US"
LBD_Configuration_CustomCharset = ""
LBD_Configuration_BannedSequences = ""

' Captcha image configuration
' ---------------------------------------------------------------------
LBD_Configuration_ImageStyle = LBD_ImageStyles("Graffiti2")
LBD_Configuration_ImageWidth = 150
LBD_Configuration_ImageHeight = 50
LBD_Configuration_ImageFormat = LBD_ImageFormats("JPEG")
LBD_Configuration_CustomDarkColor = ""
LBD_Configuration_CustomLightColor = ""
LBD_Configuration_ImageTooltip = "CAPTCHA"
LBD_Configuration_HelpLinkEnabled = True
LBD_Configuration_HelpLinkMode = LBD_HelpLinkModes("Image")
LBD_Configuration_HelpLinkUrl = ""
LBD_Configuration_HelpLinkText = ""

' Captcha sound configuration
' ---------------------------------------------------------------------
LBD_Configuration_SoundEnabled = True
LBD_Configuration_SoundStyle = LBD_RandomSoundStyle()
LBD_Configuration_SoundFormat = LBD_SoundFormats("WavPcm16bit8kHzMono")
LBD_Configuration_SoundTooltip = "Speak the CAPTCHA code"
LBD_Configuration_SoundIconUrl = "BotDetect/SoundIcon.gif"
LBD_Configuration_SoundPackageFolder = "C:\Program Files (x86)
\Lanapsoft\BotDetect 3 CAPTCHA 
Component\Asp\Redistribute\BotDetectSounds"
LBD_Configuration_WarnAboutMissingSoundPackages = True
LBD_Configuration_SoundStartDelay = 0
LBD_Configuration_SoundRegenerationMode = LBD_SoundRegenerationModes("Limited")

' Captcha reload configuration
' ---------------------------------------------------------------------
LBD_Configuration_ReloadEnabled = True
LBD_Configuration_ReloadTooltip = "Change the CAPTCHA code"
LBD_Configuration_ReloadIconUrl = "BotDetect/ReloadIcon.gif"
LBD_Configuration_AutoReloadExpiredCaptchas = True
LBD_Configuration_AutoReloadTimeout = 7200

' Captcha user input  configuration
' ---------------------------------------------------------------------
LBD_Configuration_AutoFocusInput = True
LBD_Configuration_AutoClearInput = True
LBD_Configuration_AutoUppercaseInput = True

' Captcha persistence configuration
' ---------------------------------------------------------------------
Dim LBD_Persistence : Set LBD_Persistence = Session
LBD_Configuration_UseApplicationFallback = True

%>

The ASP Captcha library configuration file defines base Captcha settings for the sample.


Please Note

The information on this page is out of date and applies to a deprecated version of BotDetect™ CAPTCHA (v3.0).

An up-to-date equivalent page for the latest BotDetect Captcha release (v4) is BotDetect v4 Captcha documentation index.

General information about the major improvements in the current BotDetect release can be found at the What's New in BotDetect v4.0 page.