Search code examples
javascriptphpjqueryrefreshcaptcha

php/javascript | How to reload only the captcha image?


I want to refresh my captcha image. I mean only the image tag.

I will show you my code first.

<?php 
include_once("./common/top.php");
require_once("./captcha/captcha.php");
?>

<div class="" style="background:#F7F7F7;">

    <div id="wrapper">
        <div id="signup" class="animate form">
            <section class="login_content">
                <form id="signup" name="signup" class="signupForm" onsubmit="return false;" method="post" action="signup.html";>
                    <h1>Create Account</h1>
                    <div>
                        <input type="email" id="inputEmail" name="inputEmail" class="form-control" placeholder="Email" required="" />
                    </div>
                    <div>
                        <input type="password" id="inputPassword" name="inputPassword" class="form-control" placeholder="Password" required="" />
                    </div>
                    <div>
                        <input type="password" id="inputCPassword" name="inputCPassword" class="form-control" placeholder="Conform Password" required="" />
                    </div>
                    <div id="RELOAD"><!-- Reload here! -->
                        <img class="captcha_code" src="<?= captcha::image() ?>" />
                        <button type="button" id="refresh_btn" class="btn btn-defualt" style="background-color:rgb(115, 135, 156); color:white;"><span class="glyphicon glyphicon-refresh"></span> Refresh</button><!-- TODO -->
                    </div><br>
                    <div>
                        <input type="text" id="inputCNum" name="inputCNum" class="form-control" placeholder="Number" required="" />
                    </div>
                    <div>
                        <a id="signup_btn" class="btn btn-default" href="index.html">Sign up</a>
                    </div>
                    <div class="clearfix"></div>
                    <div class="separator">

                        <p class="change_link">Already a member ?
                            <a href="signin.html" class="to_register"> Sign in </a>
                        </p>
                        <div class="clearfix"></div>
                        <br />
                        <div>
                            <h1><i class="fa fa-gamepad" style="font-size: 26px;"></i> GAMEPARTY</h1>
                        </div>
                    </div>
                </form>
                <!-- form -->
            </section>
            <!-- content -->
        </div>

    </div><!-- wrapper -->
</div>
<?php include_once("./common/bottom.php"); ?>

This is the html page and I want to refresh the captcha image in the div which id is RELOAD when i click the refresh_btn.

You can see the 'require_once(./captcha/captcha.php)' top of the code and that is the reason why I called the function named image from captcha class in src attribut.

The code below is the image function which is placed in captcha class.

public static function image(){
    $length = 6;
    $code = self::generate_code($length);

    ob_start();

    $image = imagecreatetruecolor(self::get_width(),self::get_height());
    $white = imagecolorallocate($image, 255, 255, 255);
    imagefilledrectangle($image, 0, 0, self::get_width(), self::get_height(), $white);

    for($dot = 0; $dot < 2000; $dot++) {
        $r = rand(0, 255);
        $g = rand(0, 255);
        $b = rand(0, 255);

        $dot_color = imagecolorallocate($image, $r, $g, $b);

        $x1 = rand(0, self::get_width());
        $y1 = rand(0, self::get_height());
        $x2 = $x1 + 1; // 1px to the right
        $y2 = $y1 + 1; // 1px to the top

        imageline($image, $x1, $y1, $x2, $y2, $dot_color);
    }


     for($start = - $length; $start < 0; $start++) {
        $color = imagecolorallocate($image, rand(0,70), rand(0,70), rand(0,70));
        $character = substr($code, $start, 1);

        $x = ($start+6) * self::$character_width;
        $y = rand(self::get_height() - 30, self::get_height() - 20);

        imagestring($image, self::$font_size, $x, $y, $character, $color);          
     }

    imagepng($image); //Output a PNG image from the given $image to either the browser or a file. *Print the raw image stream if the filepath isn't existed or null*
    imagedestroy($image); //Frees any memory associated with image image.

    $source = ob_get_contents();
    ob_end_clean();

    return "data:image/png;base64,".base64_encode($source);
}

All i want to know is how to refresh only the captcha img? Please let me know. Thank you so much.


I've changed to the reCaptcha and here is the code.

[html]

<div><!-- reCaptcha -->
    <a class="btn" id="refresh_btn" style="display:inline;"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> reset</a><div id="reCaptcha" style="transform:scale(0.8);transform-origin:0 0;margin: auto; width:70%"></div>                            
</div>

[javascript]

<script language="javascript">
var widgetId;
var refresh_btn = document.getElementById('refresh_btn'); 
var verifyCallback = function(response) {
    //console.log("verifyCallback response : " + response);
    if (response != "") {
        checkRobot();
    }
};

var onloadCallback = function() {
    widgetId = grecaptcha.render(document.getElementById('reCaptcha'), {
        'sitekey' : 'mykey',
        'callback' : verifyCallback,
        'theme' : 'light'
    });
}; 

function checkRobot() {
    $.ajax({
        type : "POST"
        , url : 'url'
        , cache : false
        , data : {"g-recaptcha-response" : $(".g-recaptcha-response").val()}
        , success : function(data){
            console.log('data : ' + data);
        }
    });
}

The function onloadCallback is called when it's loaded and the reCaptcha field is rendered by the widgetId. For this reason, I added the query behind the url in the bottom of header like this.

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"async defer></script>

I used the ajax to get the json data in checkRobot function. Here is the server side php code.

<?php 
if(isset($_POST["g-recaptcha-response"]) && $_POST["g-recaptcha-response"]) {
    //var_dump($_POST);

    $secret = "secretKey";
    $remoteip = "127.0.0.1:80"; //I'm testing on localhost.(port:80 is required)
    $response = $_POST["g-recaptcha-response"];

    $url = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$response&remoteip=$remoteip");
    //var_dump($url);
    $arr = json_decode($url, TRUE);

    if($arr["success"]) {
        echo "success";
    }else {
        echo "spam";
    }
}
?>

Solution

  • Wow! You have gone through so much trouble to create your own captcha when there are some really good ones already written.

    For example reCAPTCHA which is used right here on SO.