解决WP Rocket缓存导致Captcha Code验证码重复显示问题
Captcha Code插件与WP Rocket缓存冲突问题成因解析
问题描述
我使用了Captcha Code插件,启用WP Rocket插件后,每次刷新页面都会显示和之前相同的验证码,直到清除WP Rocket缓存后才会恢复正常。请问该问题的成因是什么?
问题成因分析
页面全量缓存固化动态验证码
WP Rocket会对页面内容进行全量缓存以提升加载速度,而你的验证码生成函数直接将验证码图片以base64编码形式嵌入页面HTML中。当WP Rocket完成页面缓存后,包含固定验证码的HTML会被重复返回给用户,刷新页面时不会触发验证码生成函数重新执行,导致显示的验证码始终不变。验证码生成逻辑未适配缓存机制
从提供的代码来看,ctl_captcha_generate_code()函数在页面渲染阶段直接生成并输出验证码的base64图片,没有向WP Rocket传递“该内容为动态、不可缓存”的信号。虽然函数最后将生成的验证码存入$_SESSION,但页面缓存会让前端显示的旧验证码与会话中存储的新验证码不匹配,不仅显示重复,还会导致后续验证失败。未配置缓存排除规则
WP Rocket默认不会自动识别动态生成的验证码内容,若未手动配置缓存排除规则(针对包含验证码的页面或验证码生成的动态区块设置不缓存),动态内容会被当作静态资源缓存起来。
验证码生成函数代码
function ctl_captcha_generate_code() { //Settings: You can customize the captcha here $image_width = 120; $image_height = 40; $characters_on_image = get_option('wpcaptcha_total_no_of_characters'); if($characters_on_image < 3 || $characters_on_image > 6) $characters_on_image = 6; $wpcaptcha_type = get_option('wpcaptcha_type'); $wpcaptcha_letters = get_option('wpcaptcha_letters'); $font = dirname(__FILE__) . '/monofont.ttf'; //The characters that can be used in the CAPTCHA code. //avoid confusing characters (l 1 and i for example) if(!empty($wpcaptcha_type) && $wpcaptcha_type == 'alphanumeric') { switch($wpcaptcha_letters) { case 'capital': $possible_letters = '23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; break; case 'small': $possible_letters = '23456789bcdfghjkmnpqrstvwxyz'; break; case 'capitalsmall': $possible_letters = '23456789bcdfghjkmnpqrstvwxyzABCEFGHJKMNPRSTVWXYZ'; break; default: $possible_letters = '23456789bcdfghjkmnpqrstvwxyz'; break; } } elseif(!empty($wpcaptcha_type) && $wpcaptcha_type == 'alphabets') { switch($wpcaptcha_letters) { case 'capital': $possible_letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; break; case 'small': $possible_letters = 'bcdfghjkmnpqrstvwxyz'; break; case 'capitalsmall': $possible_letters = 'bcdfghjkmnpqrstvwxyzABCEFGHJKMNPRSTVWXYZ'; break; default: $possible_letters = 'abcdefghijklmnopqrstuvwxyz'; break; } } elseif(!empty($wpcaptcha_type) && $wpcaptcha_type == 'numbers') { $possible_letters = '0123456789'; } else { $possible_letters = '0123456789'; } $random_dots = 0; $random_lines = 20; $captcha_text_color="0x142864"; $captcha_noice_color = "0x142864"; $code = ''; $i = 0; while ($i < $characters_on_image) { $code .= substr($possible_letters, mt_rand(0, strlen($possible_letters)-1), 1); $i++; } $font_size = $image_height * 0.75; $image = @imagecreate($image_width, $image_height); /* setting the background, text and noise colours here */ $background_color = imagecolorallocate($image, 255, 255, 255); $arr_text_color = ctl_captcha_hexrgb($captcha_text_color); $text_color = imagecolorallocate($image, $arr_text_color['red'], $arr_text_color['green'], $arr_text_color['blue']); $arr_noice_color = ctl_captcha_hexrgb($captcha_noice_color); $image_noise_color = imagecolorallocate($image, $arr_noice_color['red'], $arr_noice_color['green'], $arr_noice_color['blue']); /* generating the dots randomly in background */ for( $i=0; $i<$random_dots; $i++ ) { imagefilledellipse($image, mt_rand(0,$image_width), mt_rand(0,$image_height), 2, 3, $image_noise_color); } /* generating lines randomly in background of image */ for( $i=0; $i<$random_lines; $i++ ) { imageline($image, mt_rand(0,$image_width), mt_rand(0,$image_height), mt_rand(0,$image_width), mt_rand(0,$image_height), $image_noise_color); } /* create a text box and add 6 letters code in it */ $textbox = imagettfbbox($font_size, 0, $font, $code); $x = ($image_width - $textbox[4])/2; $y = ($image_height - $textbox[5])/2; imagettftext($image, $font_size, 0, $x, $y, $text_color, $font , $code); ob_start(); imagejpeg($image);//showing the image printf('<img src="data:image/png;base64,%s"/ width="100">', base64_encode(ob_get_clean())); imagedestroy($image);//destroying the image instance $_SESSION['captcha_code'] = $code; } function ctl_captcha_hexrgb ($hexstr) { $int = hexdec($hexstr); return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int); }
内容的提问来源于stack exchange,提问作者rk9802710
相关产品推荐
相关产品推荐

