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

Can I alter a global variable from within an event handler?

本文关键字:全局变量 事件处理 程序      更新时间:2023-09-26

我正在使用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输入字段(一个明显不正确的值)中测试了这段代码。根据警报,代码的每个部分都按照预期执行,除了validcheck_recaptcha()执行后仍然是true,尽管我知道遵循的是"错误"分支。所以问题#1是:为什么事件处理程序不能将valid设置为false ?

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

异步回调的要点是jQuery.post() 将立即返回,而无需等待来自recaptcha服务的回复。因此,当您发出"finally"警报时,recapthcha事务仍在进行,并且当它完成时将调用您的回调。然后,当警报等待您单击OK时,recaptcha回复到达并运行回调。如果注释掉警报,则在回调有机会将valid设置为false之前,提交处理程序将完成

这就是为什么首先需要提供回调,而不仅仅是读取返回值的原因。

Also:您知道在客户端检查captcha是毫无意义的,除非您稍后在服务器端重复检查,对吗?(可以说,即使您在服务器上重复它也是毫无意义的。客户端验证的目的是向用户提供故障的即时反馈,而无需等待到服务器的网络往返。如果您等到完成验证码的往返后才提交,那么在成功的情况下,除了将响应时间增加一倍之外,您什么也没做。我能想到的唯一例外是,如果您的表单包含非常大量的数据,将花费可观的时间来传输)。