如何在页面刷新/加载时刷新验证码图像?

Sop*_*oph 5 javascript captcha frameworks refresh yii

我想强制我的网站每次加载时刷新验证码图像,所以我有一个用onload()事件触发的javascript方法.这里我有以下几行:

document.getElementById('yw0_button').click;
Run Code Online (Sandbox Code Playgroud)

萤火虫没有检测到任何错误,并用于测试目的我已经加入了显示的行之后的警报权利,并提醒每个页面加载时间弹出.但是,图像不刷新!

这是我认为与视图文件相关的内容:

<?php if(extension_loaded('gd')): ?>
    <div class="row">
        <?php echo $form->labelEx($model,'verifyCode'); ?>
        <div>
            <?php
            $this->widget('CCaptcha',
                          array('showRefreshButton'=>true,
                                'buttonType'=>'button',
                                'buttonOptions'=>
                                                    array('type'=>'image',
                                                          'src'=>"/path/images/refresh-icon.png",
                                                          'width'=>30,
                                                    ),                                                            
                                'buttonLabel'=>'Refrescar imagen'),
                          false); 
            ?>
            <br>
            <?php echo $form->textField($model,'verifyCode'); ?>
        </div>
    <div class="hint">
        Porfavor ingrese las letras como las ve en la imagen superior.
        <br/>No hay distincion entre minúsculas y mayúsculas.</div>
    </div>
<?php endif; ?>
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?


@k到z刚看到这个!是的,如果你能帮我找到更合适的解决方案,那就太棒了!这是我认为与视图文件相关的内容:

<?php if(extension_loaded('gd')): ?>
        <div class="row">
            <?php echo $form->labelEx($model,'verifyCode'); ?>
            <div>
                <?php
                $this->widget('CCaptcha',
                              array('showRefreshButton'=>true,
                                    'buttonType'=>'button',
                                    'buttonOptions'=>
                                                        array('type'=>'image',
                                                              'src'=>"/path/images/refresh-icon.png",
                                                              'width'=>30,
                                                        ),                                                            
                                    'buttonLabel'=>'Refrescar imagen'),
                              false); 
                ?>
                <br>
                <?php echo $form->textField($model,'verifyCode'); ?>
            </div>
        <div class="hint">
            Porfavor ingrese las letras como las ve en la imagen superior.
            <br/>No hay distincion entre minúsculas y mayúsculas.</div>
        </div>
    <?php endif; ?>
Run Code Online (Sandbox Code Playgroud)

在控制器中,我将accessRules()方法中的授权用户权限授予验证码操作,这就是所有权限.还有什么我可以发布的吗?

Sop*_*oph 6

如果有任何人在开始使用Yii时遇到类似问题.这就是我解决触发点击的CAPTCHA问题的方法:我有一个事件触发了onload事件,其中包含以下代码:

$( '#yw0_button')点击().

肯定有一个更好的方法,我愿意接受建议!然而,作为临时解决方案,这可以正常工作,每次加载页面时刷新验证码图像.祝好运!

编辑:我做的是像我这样处理我的HTML页面的onload事件

<body onload="initialize()"> 
.. 
</body> 
Run Code Online (Sandbox Code Playgroud)

然后在我的js文件中:

function initialize() 
{ 
     $('#yw0_button').click(); 
} 
Run Code Online (Sandbox Code Playgroud)


Ezz*_*zze 5

我希望我能提出一个更好的方法来解决Soph提到的问题.我知道这不是与JavaScript相关的解决方案这个问题上瘾,但我可以看到这是最正确的方法.

我面临同样的要求 - 刷新页面刷新上的标题,但是当用户的输入在其他字段上无效时保留这一标题,因为在每次验证失败时重复新的验证码很烦人.因此,此任务看起来不会刷新POST请求上的标题并以其他方式刷新(GET请求).Soph自己提出的解决方案无法实现这一点 - 因为可以知道POST请求被发送到服务器并且客户端JavaScript无法分析它们的数据.

因此我决定看看Yii的验证码实现.它由两个system.web.widgets.captcha包在一起的类组成.前者是CCaptchaCWidget我们的视图中扩展而来的,我们在这种方式中使用以下方式将验证码添加到Web表单:

<?php 
    $this->widget("CCaptcha", array(
    'buttonLabel' => "Generate another code",
    'showRefreshButton' => false,
    'clickableImage' => true
));
?>
Run Code Online (Sandbox Code Playgroud)

后者是CCaptchaAction通过生成验证码和创建图像来提供验证码的最重要的工作.因为考虑到的Yii的设计是我们可以创建几个我们自己的类的面向对象的账户Captcha,并CaptchaAction从扩展CCaptchaCCaptchaAction比较,并把它们放在components我们的web应用程序的目录的子目录.

我对这两个类的实现如下.

run()方法CCaptchaAction是覆盖并且与原始方法非常相似,除了ifrender_refreshed设置GET参数时执行一个额外的-branch 并且在运行中生成新的验证代码并且相应的新图像被呈现并作为动作的结果返回.

refreshCaptcha类中引入了一个公共变量,默认为false表示widget的行为类似于CCaptcha一个.重写renderImage方法我们改变了负责准备小部件输出HTML代码的代码.更具说服力的是,准备用作验证码操作的链接作为标签的src属性img.在refresh成员设置为true附加render_refreshed参数的情况下,将附加到此链接.

这是CaptchaAction.php:

<?php

Yii::import("system.web.widgets.captcha.CCaptchaAction");

class CaptchaAction extends CCaptchaAction
{
    const RENDER_REFRESHED_GET_VAR = "render_refreshed";

    public function run()
    {
        if (isset($_GET[self::REFRESH_GET_VAR]))  // AJAX request for regenerating code
        {
            $code = $this->getVerifyCode(true);
            echo CJSON::encode(array(
                'hash1' => $this->generateValidationHash($code),
                'hash2' => $this->generateValidationHash(strtolower($code)),
                // we add a random 'v' parameter so that FireFox can refresh the image
                // when src attribute of image tag is changed
                'url'=> $this->getController()->createUrl($this->getId(), array(
                    'v' => uniqid()
                )),
            ));
        }
        else if (isset($_GET[self::RENDER_REFRESHED_GET_VAR]))
        {
            $this->renderImage($this->getVerifyCode(true));
        }
        else
            $this->renderImage($this->getVerifyCode());
        Yii::app()->end();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Captcha.php:

<?php

Yii::import("web.system.widgets.CCaptcha");

class Captcha extends CCaptcha
{
    public $refresh = false;

    protected function renderImage()
    {
        if (!isset($this->imageOptions['id']))
            $this->imageOptions['id'] = $this->getId();

        if ($this->refresh)
        {
            $url = $this->getController()->createUrl($this->captchaAction, array(
                'v' => uniqid(),
                CaptchaAction::RENDER_REFRESHED_GET_VAR => 1
            ));
        }
        else
        {
            $url = $this->getController()->createUrl($this->captchaAction, array(
                'v' => uniqid()
            ));
        }
        $alt = isset($this->imageOptions['alt']) ? $this->imageOptions['alt'] : '';
        echo CHtml::image($url, $alt, $this->imageOptions);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此使用非常简单.在准备网站页面的模型数据时,请执行以下操作:

...

// Creating order model's instance
$model = new MyModel();
$refreshCaptcha = true;

if (isset($_POST['MyModel']))
{
    $refreshCaptcha = false;
    ...
}

...

$this->render("myView", array(
    'model' => $model,
    'refreshCaptcha' => $refreshCaptcha
));
Run Code Online (Sandbox Code Playgroud)

之后,在myView此页面操作的模板中修改captcha的小部件调用:

<?php 
    $this->widget("Captcha", array(
    'buttonLabel' => "Generate another code",
    'showRefreshButton' => false,
    'clickableImage' => true,
    'refresh' => $refreshCaptcha
));
Run Code Online (Sandbox Code Playgroud)

并且不要忘记actions通过替换CCaptchaActionclass 来修改页面控制器的方法CaptchaAction:

public function actions()
{
    return array(
        'captcha'=>array(
            'class'=>'CaptchaAction',
            'backColor'=>0xFFFFFF
        )
    );
}
Run Code Online (Sandbox Code Playgroud)

在我看来,它按预期工作.希望这会对某人有所帮助.