简体   繁体   中英

verify captcha and contact form using php and jQuery

I'm new to jQuery.

I have an html contact form with a captcha validation.

The form uses jQuery to validate the name, email address and message.

But I'm having trouble integrating the captch validation.

The captcha is generated (by verifyimage.php ) using the following code:

<?php
session_start();
error_reporting( 0 );
if( !function_exists( "imagecreatefrompng" ) )
{
    exit( "You need to recompile with the GD library included in PHP for this feature to be able to function" );
}
$alphanum = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
$rand = substr( str_shuffle( $alphanum ), 0, 6 );
$image = imagecreatefrompng( "../images/verify.png" );
$textColor = imagecolorallocate( $image, 150, 150, 150 );
imagestring( $image, 5, 14, 22, $rand, $textColor );
$_SESSION['image_random_value'] = md5( $rand );
header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
header( "Last-Modified: ".gmdate( "D, d M Y H:i:s" )." GMT" );
header( "Cache-Control: no-store, no-cache, must-revalidate" );
header( "Cache-Control: post-check=0, pre-check=0", false );
header( "Pragma: no-cache" );
header( "Content-type: image/png" );
imagepng( $image );
imagedestroy( $image );
?>

The HTML for the form is as follows:

<!-- Contact Form -->
<div id="contactForm">
        <form action="/contact.php" method="post">
        <div class="oneThird">
            <div class="row">
                <label for="contactName">Full Name</label>
                <input id="contactName" name="contactName" type="text" />
            </div>
            <div class="row topMargin">
                <label for="contactEmail">Email Address</label>
                <input id="contactEmail" name="contactEmail" type="text" />
            </div>
                        <div class="row topMargin">
                <label for="contactVerify">Captcha</label>
                <input style="background-image: url(/php/verifyimage.php);" id="contactVerify" name="contactVerify" type="text" />
            </div>
                    </div>
        <div class="twoThird lastColumn">
            <div class="row">
                <label for="contactMessage">Message</label>
                <textarea id="contactMessage" name="contactMessage" cols="10" rows="9"></textarea>
            </div>
        </div>
        <div class="clearfix">
        </div>
        <button type="submit" class="colorButton">Send Message</button>
    </form>
    </div>

And the jQuery includes the following code related to validating the forms name, email, and message sections:

// Contact
    if ($('#contactForm').length != 0)
    {
        var labelName = $('#contactForm label[for="contactName"]').text();
        var labelEmail = $('#contactForm label[for="contactEmail"]').text();
        var labelMessage = $('#contactForm label[for="contactMessage"]').text();
        var emailPattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);

        if ($('#contactVerify').length != 0)
        {
            var labelVerify = $('#contactForm label[for="contactVerify"]').text();
        }

        $('#contactForm button').click(function()
        {
            if ($('#contactName').val() == '')
            {
                $('#contactForm label[for="contactName"]').addClass('error').text(labelName + ' is required');
            }
            else
            {
                $('#contactForm label[for="contactName"]').removeClass('error').text(labelName);
            }

            if ($('#contactEmail').val() == '')
            {
                $('#contactForm label[for="contactEmail"]').addClass('error').text(labelEmail + ' is required');
            }
            else if (!emailPattern.test($('#contactEmail').val()))
            {
                $('#contactForm label[for="contactEmail"]').addClass('error').text(labelEmail + ' is invalid');
            }
            else
            {
                $('#contactForm label[for="contactEmail"]').removeClass('error').text(labelEmail);
            }

            if ($('#contactMessage').val() == '')
            {
                $('#contactForm label[for="contactMessage"]').addClass('error').text(labelMessage + ' is required');
            }
            else
            {
                $('#contactForm label[for="contactMessage"]').removeClass('error').text(labelMessage);
            }

            if (typeof labelVerify != 'undefined')
            {
                if ($('#contactVerify').val() == '')
                {
                    $('#contactForm label[for="contactVerify"]').addClass('error').text(labelVerify + ' is required');
                }
                else
                {
                    $('#contactForm label[for="contactVerify"]').removeClass('error').text(labelVerify);
                }

            }

            if ($('#contactForm label.error').length == 0)
            {
                $('#contactForm form').append('<input type="hidden" value="1" name="contactValid" />');
            }
            else
            {
                return false;
            }
        });
    }

I'm stuck as to how I implement the captcha validation. Do I include it in the contact.php the form is posted to?

Or can I validated the captcha before the form is posted? like the email address is?

I've tried adding:

<?php
session_start();
$cap = 'notEq';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    if (md5($_POST['contactVerify']) == $_SESSION['image_random_value']) {
        // contactVerify verification is Correct. Do something here!
        $cap = 'Eq';
    } else {
        // contactVerify verification is wrong. Take other action
        $cap = '';
    }
}
?>

to the top of the HTML form. And then also adding:

var capch = '<?php echo $cap; ?>';
                if(capch != 'notEq'){
                    if(capch == 'Eq'){
        // My PHPMailer script //
                    }
                    else{
                        $('#contactForm label[for="contactVerify"]').addClass('error').text(labelVerify + ' is invalid');
                    }
                }                

            });

as a script. But without any joy. The form gets sent regardless of whether the captcha is invalid or not.

Any help appreciated.

You will want to save the captcha to the $_SESSION in the PHP and check it regardless of local validation.

Next, the reason why people rarely use local captcha verification is because it would require a "check" to the server, the script would ask the server if it is correct and then tell the user if it isn't (otherwise the web browser would know the value for the captcha which would defeat the purpose as any coder could grab this and exploit it).

What I would recommend doing is use a asynchronous form submit (hide the form as it is submitted without refreshing the page, use javascript to submit the form instead of a full page reload to /contact.php. Next, have the HTTP response be either "success" or a reason why it failed returned by the PHP. When the client receives a fail response, it will show the form again (note that since there was no refresh the data will still be in the fields), give a new captcha so that someone couldn't constantly poll the same captcha , and give the user some indication that what they've done has failed.

The question at hand aside, all of this is extremely easy in Angular JS . I highly recommend it.

Hope this helped!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM