常不显示,因浏览器发起请求时可能未携带cookie导致session_start()失败、脚本未设置content-type响应头、或被缓存;需确保verify.php开头无输出、调用session_start()、设header('content-type: image/png')并加防缓存头。

PHP生成的验证码图片,前端不能直接用 <img src="verify.php"> 就完事——默认会因缺少会话上下文或响应头问题导致空白、404 或 CORS 报错。
为什么 <img src="verify.php"> 常常不显示
多数 PHP 验证码脚本(如基于 $_SESSION 的)依赖会话初始化,但浏览器发起 <img> 请求时不会自动携带 cookie(尤其跨域或首次访问),session_start() 失败 → 验证码图像不输出;另外,如果脚本没设 Content-Type: image/png,浏览器拒绝渲染;还有可能被浏览器缓存(同一 URL 永远显示旧图)。
实操建议:
- 确保
verify.php开头调用session_start(),且无任何输出(包括空格、BOM) - 在输出图像前加
header('Content-Type: image/png');(或image/jpeg) - 强制禁用缓存:
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); - 前端
<img>的src加时间戳防缓存:verify.php?t== time() ?>
前端如何安全获取并刷新验证码字母
单纯靠 <img> 标签无法知道后端生成的验证码文本(这是安全设计),但前端需要“点击刷新”和“提交校验”两个动作。关键点是:刷新必须重置会话中的验证码值,且避免 XSS 泄露真实值。
实操建议:
- 不要用 AJAX 直接请求
verify.php并解析图像内容(不可行) - 刷新按钮应触发一个轻量接口(如
refresh_captcha.php),它只调用session_regenerate_id(true)+ 重新生成验证码并存入$_SESSION['captcha_code'],然后返回成功状态(JSON) -
<img>的src改为指向该接口的带参 URL:verify.php?r== uniqid() ?>,每次刷新都换随机参数,绕过缓存 - 禁止在 JS 中打印或 alert
$_SESSION['captcha_code']—— 后端绝不向前端明文返回验证码字符串
PHP 验证码常见字母混淆问题(0/O, 1/l/I)怎么规避
默认用 rand() 拼字母容易生成视觉难区分字符,导致用户反复输错。这不是前端能解决的,必须在 PHP 生成逻辑里过滤。
实操建议:
- 定义白名单字符集:
$chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';(去掉 0,O,1,l,I) - 用
str_shuffle()+substr()取值,别用array_rand()(可能重复) - 生成后存入
$_SESSION['captcha_code']时统一转大写(避免前端大小写判断歧义) - 图像上加轻微旋转(
imagettftext()配合rand(-15,15))可提升机器识别难度,但别过度影响人眼
AJAX 提交时后端校验失败的典型原因
用户填了验证码,AJAX 提交后端却总提示“错误”,大概率不是逻辑错,而是会话断裂或编码问题。
实操建议:
- 检查前端是否带 cookie:AJAX 请求需设
credentials: 'include'(fetch)或xhrFields: { withCredentials: true }(jQuery) - 确认前后端域名/端口完全一致(
localhost:8080和localhost视为跨域) - 后端校验前先
if (empty($_SESSION['captcha_code'])) die('expired');,避免空值比较 - 严格用
hash_equals($_SESSION['captcha_code'], $_POST['captcha'])校验,防止时序攻击 - 校验成功后立即
unset($_SESSION['captcha_code']),防止重放
最易被忽略的是:本地开发用 Chrome 访问 file:// 协议时,session_start() 会静默失败,图像必然空白——必须走 HTTP(S) 服务(哪怕用 php -S 起个临时服务器)。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











