yii ajax验证失败返回提示,Yii2验证码Captcha使用Ajax无法验证的处理方法

因Yii2验证码Captcha原校验方式有bug,总是报错:验证码不正确,导致无法实现Ajax验证,今天研究了一下Yii2的源代码,把这个问题解决掉了。

主要解决方法:

1)还是使用Yii2的yii\captcha\CaptchaAction,进行验证码的生成、显示等操作。

2)但使用自定义的codeVerify验证方法进行验证,避开Yii2的验证Bug

3)验证完成后要重新生成新的验证码。

有其他特殊需求可以在这些代码中自己添加即可。

源代码:

文件位置:D:\phpwork\news\models\RegisterForm.php

class RegisterForm extends Model{

public function rules(){

return [

//替代['verifyCode', 'captcha'],

['verifyCode', 'codeVerify'],

......

];

}

//使用自定义的codeVerify验证方法进行验证,避开Yii2的验证Bug

public function codeVerify($attribute){

//参数:'captcha',即控制器中actions()内的名称'captcha';Yii::$app->controller,调用验证的当前控制器(必须设置)

$captcha_validate = new \yii\captcha\CaptchaAction('captcha',Yii::$app->controller);

if($this->$attribute){

$code = $captcha_validate->getVerifyCode();

if($this->$attribute!=$code){

$this->addError($attribute, 'The verification code is incorrect.');

}

}

}

文件位置:D:\phpwork\news\controllers\SiteController.php

class SiteController extends CommonController{

public function actions(){

return [

'captcha' => [

'class' => 'yii\captcha\CaptchaAction',

],

];

}

public function actionRegister(){

$model = new RegisterForm();

if ($model->load(Yii::$app->request->post())) {

if (Yii::$app->request->isAjax) {

Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

return \yii\widgets\ActiveForm::validate($model);

}

if($model->validate()){

$error=$model->save();

if($error) {

return $this->errorDisplay($error);

}else{

//数据存储成功后,要重新生成新的验证码,否则原验证码不会改变

$captcha_validate = new \yii\captcha\CaptchaAction('captcha',$this);

$captcha_validate->getVerifyCode(true);

Yii::$app->session->setFlash('success');

return $this->refresh();

}

}else{

return $this->errorDisplay($model->getErrors());

}

}else{

return $this->render('register', [

'model' => $model,

]);

}

}

文件位置:D:\phpwork\news\views\site\register.php

/* @var $this yii\web\View */

/* @var $form yii\bootstrap\ActiveForm */

/* @var $model app\models\ContactForm */

use yii\helpers\Html;

use yii\bootstrap\ActiveForm;

use yii\captcha\Captcha;

$this->title = 'User Register';

$this->params['breadcrumbs'][] = $this->title;

?>

= Html::encode($this->title) ?>

<?php if (Yii::$app->session->hasFlash('success')): ?>

Register successful!

You can now Login.

'id' => 'contact-form',

]); ?>

= $form->field($model, 'member',['enableAjaxValidation'=>true])->textInput(['autofocus' => true])->hint('Can be chinese,grapheme or number.Only use to login,not public display!') ?>

= $form->field($model, 'memkey')->passwordInput() ?>

= $form->field($model, 'memkey_repeat')->passwordInput() ?>

= $form->field($model, 'nickname',['enableAjaxValidation'=>true])->textInput()->hint('Can be chinese,grapheme or number,can have blank space.For public display only!') ?>

= $form->field($model, 'verifyCode',['enableAjaxValidation'=>true])->widget(Captcha::className(), [

'captchaAction'=>'site/captcha',

'imageOptions'=>['id'=>'captchaimg','alt'=>'点击换图','title'=>'点击换图', 'style'=>'cursor:pointer'],

'template' => '

{image}
{input}
',

]) ?>

= Html::submitButton('Submit', ['class' => 'btn btn-primary', 'name' => 'contact-button']) ?>

关于Yii2图形验证码Bug产生的原因

Yii2图形验证码Bug产生的原因:首次验证通过后会重新生成验证码,导致二次验证失败!

具体执行过程:方法validate($input, $caseSensitive)在Ajax进行第一次验证后,$valid为true,导致$this->getVerifyCode(true);被执行,即重新生成了新的VerifyCode,当$model->verify()进行第二次验证时,则必定失败(新的VerifyCode与刚才输入的已经不一样了!),以下是Yii2原码:

文件位置:D:\phpwork\news\vendor\yiisoft\yii2\captcha\CaptchaAction.php

public function validate($input, $caseSensitive){

$code = $this->getVerifyCode();

$valid = $caseSensitive ? ($input === $code) : strcasecmp($input, $code) === 0;

$session = Yii::$app->getSession();

$session->open();

$name = $this->getSessionKey() . 'count';

$session[$name] = $session[$name] + 1;

//Bug由以下三行代码产生:

if ($valid || $session[$name] > $this->testLimit && $this->testLimit > 0) {

$this->getVerifyCode(true);

}

return $valid;

}

(全文完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值