問題: 驗證碼圖片由 captcha.php 產生,若直接 AJAX 請求該檔案會同時下載圖片二進位資料,無法單純取得驗證碼字串。
解法: 分離「驗證碼生成」與「驗證碼取得」兩個端點:
captcha.php:生成圖片,將驗證碼存入 $_SESSION['captcha']。get_captcha.php:session_start(); echo $_SESSION['captcha'] ?? ''; 純文字回傳。前端 AJAX 請求 get_captcha.php 取得驗證碼,再與用戶輸入比對。
<?php
session_start();
header('Content-Type: image/png');
$im = imagecreatetruecolor(80, 30);
$bg = imagecolorallocate($im, 240, 240, 240);
imagefill($im, 0, 0, $bg);
$code = '';
for ($i = 0; $i < 4; $i++) {
$color = imagecolorallocate($im, mt_rand(50,150), mt_rand(50,150), mt_rand(50,150));
$char = chr(mt_rand(65, 90)); // A-Z
$code .= $char;
imagestring($im, 5, 5 + $i * 18, 5, $char, $color);
}
// 干擾線
for ($i = 0; $i < 20; $i++) {
$color = imagecolorallocate($im, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
imageline($im, mt_rand(0,80), mt_rand(0,30), mt_rand(0,80), mt_rand(0,30), $color);
}
imagepng($im);
imagedestroy($im);
$_SESSION['captcha'] = $code; // 關鍵:存入 Session
<?php
session_start();
echo $_SESSION['captcha'] ?? '';
$('#captcha_input').on('blur', function() {
var userInput = $(this).val().toUpperCase();
$.get('get_captcha.php', function(serverCode) {
if (userInput === serverCode.trim()) {
$('#captcha_tip').text('✓ 正確').css('color', 'green');
} else {
$('#captcha_tip').text('✗ 錯誤').css('color', 'red');
$('#captcha_img').attr('src', 'captcha.php?t=' + Date.now()); // 刷新
}
});
});
<?php
session_start();
if (strtoupper($_POST['captcha']) !== ($_SESSION['captcha'] ?? '')) {
die('驗證碼錯誤');
}
// 繼續業務邏輯...
captcha_login, captcha_reg)。