第二层内功 - 验证码

  • 作者:KK

  • 发表日期:2017.3.31


第一步:显示验证码图片

控制器要配置一个action映射,将显示验证码图片的网址映射给yii\captcha\CaptchaAction

为了快速上手,请你一定要在Site控制器下进行映射!

class SiteController extends \yii\web\Controller{
	public function actions(){
		return [
			//默认情况下一定要命名为 captcha,后面再教你改
			'captcha' => [
				'class' => 'yii\captcha\CaptchaAction',
				'width' => 220, //宽高
				'height' => 70,
				'padding' => '0', //内边距
				'transparent' => true, //透明底
				'backColor' => 0x000000, //背景色
				'foreColor' => 0xFFFFFF, //文字色
			],
		];
	}
}

这样就能实现访问?r=site/captcha的时候能看到一张验证码图片,而这张图片就是yii\captcha\CaptchaAction::run输出的

实际上这个地址每被访问一次的时候,Yii除了生成验证码图片显示出来之余,它还在session里存好了验证码的值,以便我们未来提交上去时能比较是否输入正确


第二步:设定前端的输入表单

我这里以自定义的表单演示:

<form method="post" action="/index.php?r=site/login">
	<!--下面加onclick是为了实现点击刷新为了实现点击刷新"/index.php?r=site/captcha" /><br/>
	<input type="text" placeholder="请输入验证码" name="verifyCode" /><br/>
	<button type="submit">提交

第三步:定义一个表单模型

验证规则的名称就是captcha

class LoginForm extends \yii\base\Model{
	public function rules(){
		return [
			['captcha', 'captcha', 'message' => '验证码错误'],
		];
	}
}

第四步:控制器调用

//这个login方法先放Site控制器吧,其实无所谓

public function actionLogin(){
	$form = new LoginForm();
	$form->load(Yii::$app->request->post(), '');
	if($form->validate()){
		echo '验证码正确';
	}else{
		echo current($form->firstErrors); //验证码错误
	}
}

刷新验证码

错误的做法

如果将上面的img标签改成<img src="/index.php?r=site/captcha" onclick="this.src=/index.php?r=site/captcha&v=随机数" />这样的话即使是加了随机数,但点击后重新加载的验证码都是一模一样不会变化的,不信你直接在浏览器上访问http://localhost/index.php?r=site/captcha&v=111然后再访问http://localhost/index.php?r=site/captcha&v=222,都会是同一张图片

正确的做法

要实现刷新验证码先要通过ajax获取一个不同的验证码地址:

$.get('/index.php?r=site/captcha&refresh=1', function(result){

	//这就是新的验证码地址,类似 /index.php?r=site%2Fcaptcha&v=58e8de5c89096
	console.log(result.url);
});

注意这里ajax请求的地址多了个参数叫refresh,值为1

ajax成功得到这个新的url后,将它设置到img的src属性里就可以更新验证码图片了


示例代码下载

http://pan.baidu.com/s/1i5Fo5lb

这个示例并没有使用site/captcha这个路由来产生验证码,而是使用了abc/xxx

在这种情况下(非site/captcha)要在表单模型rules里定义规则时多加一个captchaAction才能成功校验,未来我会发表文章专门讲讲这个