我可以在事件处理程序中更改全局变量吗?

时间:2011-08-09 18:27:13

标签: javascript jquery ajax global-variables captcha

我正在使用AJAX验证CAPTCHA输入。我意识到我无法从AJAX调用的成功处理程序返回一个值,因此我创建了一个全局变量,因此成功处理程序和验证函数可以相互通信。但它并没有以最错误的方式运作。首先,代码:

jQuery('#contact').submit(function(event) {
        if (validate_form())
        {
            submit_form(event);
        }
        else
        {
            return false;
        }
    });

var valid = true;

function validate_form()
{
    valid = true;

    // test form stuff here
    // if something goes wrong valid will be set to false

    if (!valid)
    {
        alert("form is not valid, refreshing captcha");
        // refresh form
        // ....
    }
    else
    {
        alert("form is valid, checking captcha");
        check_recaptcha();
    }

    alert("finally, form is:" + valid);
    return valid;
}

function check_recaptcha()
{
    alert("checking captcha now");
    // take only recaptcha values from form
    var recaptcha_vals = jQuery(':input[name^="recaptcha"]').serialize();
    jQuery.post('recaptcha.php', recaptcha_vals, function(data) {
        alert("recaptcha post has succeeded!");
        if (data == '1\n' /*success!*/)
        {
            alert("recaptcha is correct!");
            jQuery('#recaptcha_error').empty();
        }
        else
        {
            alert("recaptcha is incorrect!");
            show_recaptcha();
            jQuery('#recaptcha_error').html("<p class=\"error\">CAPTCHA was incorrect, please try again.</p>");
            valid = false;
        }
    });
}

我在CAPTCHA输入字段中没有任何内容测试此代码(显然是不正确的值)。根据警报,代码的每个部分都按预期完成,但validtrue执行后仍然check_recaptcha(),即使我知道遵循“不正确”分支。问题#1是:为什么事件处理程序无法将valid设置为false

这是奇怪的地方。在上面的场景中,即使validate_form()返回true(根据警报),表单也不会提交。但是,当我注释掉所有警报并使用完全相同的输入再次尝试时,表单将提交。所以问题#2是:这有什么用?#1更重要的是。

2 个答案:

答案 0 :(得分:2)

异步回调的意思是jQuery.post() 将立即返回,而不等待recaptcha服务的回复。因此,当您发出“最终”警报时,重新开始转换仍在进行,并且在完成后将调用您的回调。然后,当您的警报等待您单击“确定”时,重新计数回复将到达并且您的回调将运行。如果您注释掉警报,则提交处理程序将在之前完成,回调有可能将有效设置为false。

为什么你需要首先提供一个回调,而不是只是读取一个返回值。

同样:您知道在客户端检查验证码是没有意义的,除非您稍后在服务器端重复检查,对吧? (可以说,即使你在服务器上重复它也没有意义。客户端验证的目的是为用户提供有关故障的即时反馈,而无需等待网络往返服务器。如果你等到提交直到你完成了往返检查验证码,除了成功案例中的响应时间加倍外,你只做了一件事。我能想到的唯一例外是你的表格中是否包含大量需要花费大量时间才能传输的数据。

答案 1 :(得分:0)

我在这里找到了答案:Javascript Local vs Global。不过,我反对这个答案的建议,并确实将我的请求设置为同步,这在我的应用程序环境中运行良好。