如何让我的CAPTCHA脚本具有刷新链接?

时间:2011-09-03 18:00:20

标签: php javascript jquery captcha

我有一个验证码脚本,效果很好。但是,我不知道如何刷新它。

这是verificationimage.php

<?php

header('Content-type: image/jpeg');

$width = 50;
$height = 24;

$my_image = imagecreatetruecolor($width, $height);

imagefill($my_image, 0, 0, 0xFFFFFF);

// add noise
for ($c = 0; $c < 40; $c++){
    $x = rand(0,$width-1);
    $y = rand(0,$height-1);
    imagesetpixel($my_image, $x, $y, 0x000000);
    }

$x = rand(1,10);
$y = rand(1,10);

$rand_string = rand(1000,9999);
imagestring($my_image, 5, $x, $y, $rand_string, 0x000000);

setcookie('tntcon',(md5($rand_string).'a4xn'));

imagejpeg($my_image);
imagedestroy($my_image);
?>

并且,页面的格式为:

<label for="verif_box" style="margin-top:10px;">Image Verification:</label>

<input name="verif_box" type="text" id="verif_box" autocomplete="off" minlength="4" maxlength="5" class="text" />

<img id="captcha" src="verificationimage.php?<?php echo rand(0,9999);?>" alt="This form can't be submitted because images aren't displayed" title="Verification image, type it in the box" width="50" height="24" align="absbottom" onclick="$('#verif_box').focus();" style="cursor:pointer;" /> &nbsp; (<a href="#captcha" class="fancybox">what's this?</a>)
<br />
<br />

    <?php 
    //if the variable "wrong_code" is sent from previous page then display the error field
    if(isset($_GET['wrong_code'])){?>
    <div style="border:1px solid #990000; background-color:#D70000; color:#FFFFFF; padding:4px; padding-left:6px;width:295px;">The code you entered does not match the image. Please try typing what you see in the image to the right again.</div><br /> 
    <?php ;} ?>

以下是mailer.php中发生的事情:

// check to see if verificaton code was correct
if(md5($verif_box).'a4xn' == $_COOKIE['tntcon']){
    // if verification code was correct send the message and show this page

    mail("email@domain.com", 'New WeeBuild Support Ticket: '.$subject, $emailContent, $headers);

    mail($email, 'Thank you for contacting WeeBuild Support! (#'.$ticket.')', $emailContents, $headers2);

    // add to database

    $today = getdate();
        $theDate = $today["weekday"].", ".$today["month"]." ".$today["mday"].", ".$today["year"];

    mysql_select_db("database_name", $con);
        $sql="INSERT INTO table_name (name, email, subject, message, ticket, ip_address, created)
        VALUES ('$_POST[name]','$_POST[email]','$_POST[subject]','$_POST[message]','$ticket','$_SERVER[REMOTE_ADDR]','$theDate')";

if (!mysql_query($sql,$con))
  {
  die('Error: ' . mysql_error());
  }

  //close the database connection
  mysql_close($con);

    // delete the cookie so it cannot sent again by refreshing this page
    setcookie('tntcon','');

} else if(isset($message) and $message!=""){

    // if verification code was incorrect then return to contact page and show error

    header("Location: index.php?name=$name&subject=$subject&email=".urlencode($email)."&message=".urlencode($message)."&wrong_code=true");
    exit;
}

目前这一切都很好,但我怎样才能刷新验证码呢?我试过这样做:

<script>
$(document).ready(function() {
$('#refresh').click(function() {
$('img#captcha').attr('src','verificationimage.php?<?php echo rand(0,9999);?>');
});
});
</script>
<a href="#" id="refresh">refresh</a>

但是,它不起作用。

顺便说一句,我不想​​使用reCaptcha,我只是这样做,因为对我来说,reCaptcha看起来很难用我的东西来设置。

3 个答案:

答案 0 :(得分:2)

我的回答类似于评论中的回答,很可能在刷新时使用了缓存副本,但使用正确的方法确保浏览器不缓存该图像而不是随机字符串。在图像生成页面上,添加:

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");

答案 1 :(得分:1)

由于图片标签有一个id,这是选择器唯一需要的东西 我认为问题来自浏览器缓存:因为随机字符串是由 PHP 生成的,刷新按钮只能工作一次(因为下一次调用将使用相同的字符串,浏览器将使用缓存版本)。

这应该可以解决问题,每次按下按钮时都会生成一个新的随机字符串:

$(function() {
    $('#refresh').click(function() {
        $('#captcha').attr('src', 'verificationimage.php?' + new Date().getTime());
        return false;
    });
});

答案 2 :(得分:1)

除了使用cookie之外,还有更好,更安全的方式来发送CAPTCHA信息以进行验证。至少,我建议使用会话变量,但使用命名会话和IP验证,以防止会话劫持。为您的CAPTCHA图像生成脚本添加热链接防护也是一个非常好的主意,这样有人就不能只在浏览器中提取CAPTCHA图像。只是一个建议。 :)

要使用热链接防护,只需将以下代码添加到图像创建脚本的顶部:

if (!isset($_SERVER['HTTP_REFERER']) or checkValidReferer() === false) die();

function checkValidReferer() {
  $out = false;
  $ref = $_SERVER['HTTP_REFERER'];
  $lh = $_SERVER['HTTP_HOST'];
  if (stripos($ref,$lh) !== false) $out = true;
  return $out;
}

如果引用者的基本URL都存在,则上述代码输出一个好的图像,并且与图像脚本的基本URL相同。这可以防止图像被用在除应该的位置之外的其他地方。