Javascript和AJAX,仅在使用alert()时有效

时间:2009-08-12 17:07:43

标签: javascript ajax alert

我的javascript出现问题。这看起来很奇怪。这是正在发生的事情。我有一个表单,在用户提交之后,它调用一个函数(onsubmit事件)来验证提交的数据,如果有什么不好或者如果用户名/电子邮件已经在数据库中(使用此部分的ajax)它将返回false并使用DOM显示错误。这是下面的代码。有什么奇怪的,它只有在我使用空警报('')消息时才有效,没有它,它就行不通。谢谢你的帮助。

//////////////////////////////////////

function httpRequest() {
    var xmlhttp;

    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        // code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        alert("Your browser does not support XMLHTTP!");
    }

    return xmlhttp;
}

function validateRegForm(reg) {

    var isValidForm = true;
    var warningIcon = "";//for later in case we want to use an icon next to warning msg

    with(reg) {


        var regFormDiv = document.getElementById("registration_form");

        //Check if dynamic div exist, if so, remove it
        if(document.getElementById('disp_errors') != null) {
            var dispErrorsDiv = document.getElementById('disp_errors');
            document.getElementById('reg_form').removeChild(dispErrorsDiv);
        }           

        //Dynamically create new 'div'
        var errorDiv = document.createElement('div');
        errorDiv.setAttribute('id','disp_errors');
        errorDiv.setAttribute('style','background-color:pink;border:1px solid red;color:red;padding:10px;');
        document.getElementById('reg_form').insertBefore(errorDiv,regFormDiv);




        var xmlhttp = httpRequest();
        var available = new Array();
        xmlhttp.onreadystatechange = function() {
            if(xmlhttp.readyState == 4)
            {   
                var response = xmlhttp.responseText;
                if(response != "") {

                    //Return values
                    var newValue = response.split("|");
                    available[0] = newValue[0]; 
                    available[1] = newValue[1]; 
                }
            }
        }

        xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+u_username.value+"&email="+u_email.value+"",true);
        xmlhttp.send(null);


        alert(' '); ////////////WITHOUT THIS, IT DOESN'T WORK. Why?

        if(available[1] == "taken") {
            errorDiv.innerHTML += warningIcon+'Username is already taken!<br />';
            isValidForm = false;
        } else if(u_username.value.length < 4){
            errorDiv.innerHTML += warningIcon+'Username must be more than 4 characters long!<br />';
            isValidForm = false;
        } else if(u_username.value.length > 35) {
            errorDiv.innerHTML += warningIcon+'Username must be less than 34 characters long!<br />';
            isValidForm = false;
        }


        if(available[0] == "taken") {
            errorDiv.innerHTML += warningIcon+'Email address entered is already in use!<br />';
            isValidForm = false;
        } else if(u_email.value == ""){
            errorDiv.innerHTML += warningIcon+'Email address is required!<br />';
            isValidForm = false;
        } else {
            //Determine if email entered is valid
            var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
            if (!filter.test(u_email.value)) {
                errorDiv.innerHTML += warningIcon+'Email entered is invalid!<br />';
                u_email.value = "";
                isValidForm = false;
            }
        }


        if(u_fname.value == ""){
            errorDiv.innerHTML = warningIcon+'Your first name is required!<br />';
            isValidForm = false;
        }

        if(u_lname.value == ""){
            errorDiv.innerHTML += warningIcon+'Your last name is required!<br />';
            isValidForm = false;
        }



        if(u_password.value.length < 4){
            errorDiv.innerHTML += warningIcon+'Password must be more than 4 characters long!<br />';
            isValidForm = false;
        } else if(u_password.value.length > 35) {
            errorDiv.innerHTML += warningIcon+'Password must be less than 34 characters long!<br />';
            isValidForm = false;
        } else if (u_password.value != u_password2.value) {
            errorDiv.innerHTML += warningIcon+'Password and re-typed password don\'t match!<br />';
            isValidForm = false;
        }


        if(u_squestion.value == ""){
            errorDiv.innerHTML += warningIcon+'A security question is required!<br />';
            isValidForm = false;
        }

        if(u_sanswer.value == ""){
            errorDiv.innerHTML += warningIcon+'A security answer is required!<br />';
            isValidForm = false;
        }

        if(u_address.value == ""){
            errorDiv.innerHTML += warningIcon+'Address is required!<br />';
            isValidForm = false;
        }

        if(u_city.value == ""){
            errorDiv.innerHTML += warningIcon+'City is required!<br />';
            isValidForm = false;
        }

        if(u_state.value == ""){
            errorDiv.innerHTML += warningIcon+'State is required!<br />';
            isValidForm = false;
        }

        if(u_zip.value == ""){
            errorDiv.innerHTML += warningIcon+'Zip code is required!<br />';
            isValidForm = false;
        }

        if(u_phone.value == ""){
            errorDiv.innerHTML += warningIcon+'Phone number is required!<br />';
            isValidForm = false;
        }

        if(isValidForm == false)
            window.scroll(0,0);

        return isValidForm;
    }

}

10 个答案:

答案 0 :(得分:11)

alert()会有所帮助,因为这会延迟处理该函数中剩余的javascript(从alert()到底部的所有内容),留出足够的时间来完成AJAX请求。 AJAX中的第一个字母代表“异步”,这意味着(默认情况下)响应将在“未来的某个时刻”进行,但不是立即进行。

一个修复(您应该实现)是使处理同步(通过将open()的第三个参数更改为false),这将停止进一步处理您的脚本(以及整个网页)直到请求返回。这很糟糕,因为它会有效地冻结Web浏览器,直到请求完成。

正确的解决方法是重构代码,以便任何依赖于AJAX请求结果的处理都进入onreadystatechange函数,并且不能在启动AJAX请求的main函数中。

通常处理的方法是修改你的DOM(在发送AJAX请求之前)使表单只读并显示某种“处理”消息,然后在AJAX响应处理程序中,如果一切正常(服务器正确响应验证成功)在表单上调用submit(),否则使表单再次变为可用并显示任何验证错误。

答案 1 :(得分:3)

问题是XMLHTTPRequest是异步的 - 它在后台发送请求,而不是等待它完成。

alert语句导致代码等待,直到用户单击“确定”,在此期间请求完成。

您需要使用onreadystatechange事件,如下所示:

xmlhttp.onreadystatechange = function() {
    if(xmlhttp.readyState==4) {
        // Do things
    }
};

收到响应后,将调用您为此属性指定的方法。 (在其他时候,这就是为什么你需要检查readyState是4)

答案 2 :(得分:2)

您正在发送请求异步,因为:

xmlhttp.open(..., true);

true作为第三个参数传递给open()意味着代码将在结果返回之前继续运行。

alert()在后​​续代码运行之前完成异步请求时间。

我通常建议将依赖于AJAX调用结果的所有代码移动到回调中:

if(xmlhttp.readyState == 4)

阻止,但在您的情况下,您需要调用的结果才能知道从验证函数返回什么。在这种情况下,您必须将false传递给open(),才能使用同步通话。然后你的后续代码将不会运行,直到响应回来。

答案 3 :(得分:0)

这是因为您的AJAX调用是异步的。 xmlhttp.send()之后的代码立即执行。它不会等待你的ajax调用结束(除非你发出警报)。

将ajax调用后要执行的所有代码移动到回调方法,以确保在调用完成后运行它。

[编辑]:除了问题之外,我认为使用AJAX来验证表单然后允许用户提交通常的方式对我来说似乎有些奇怪。

您可以将验证分为两部分吗?一个可以完全在客户端完成,另一个涉及服务器端验证。您可以在提交时完全在服务器端执行第二部分,并将错误返回给客户端。

另一个选择是完全避免传统的提交。既然你正在进行ajax调用,为什么不在ajax调用本身中进行保存/编辑/删除需要提交?但请记住,如果用户禁用了javascript,您仍需要支持常规提交。

答案 4 :(得分:0)

这些人是对的,但我也肯定会从验证方法中返回bool,因此如果表单无效,表单的提交将被取消。

有些事情:

<form onsubmit="return IsValid();">

...

</form>

您也可以始终从 validateRegForm 返回false,并让 xmlhttp.onreadystatechange = function()提交表单(如果有效),或以其他方式显示您的错误消息。

答案 5 :(得分:0)

你必须将第三个参数传递给xmlhttp.open()为false,然后才能正常工作

答案 6 :(得分:0)

当我使用type =&#34; submit&#34;时遇到同样的问题,例如:

<button type="submit" class="btn btn-default" name="btn-login" id="btn-login" onclick="submitForm()">
  <span class="glyphicon glyphicon-log-in"></span> &nbsp; Sign In

但我将其更改为键入=&#34;按钮&#34;它有效。

答案 7 :(得分:0)

<button onclick="AddComment();">Comment</button>

这是我的 ajax 代码开始的地方,AddComment() 函数点击了一个隐藏的 Asp:Button,它将通过更新面板向后端发送一个 ajax 调用...

为了解决这个问题,我所做的只是将 return false; 添加到我的按钮中。

<button onclick="AddComment(); return false;">Comment</button>

答案 8 :(得分:-1)

我遇到了同样的问题。删除alert("")后,它无效。我想通了,这就是交易。

在HTML中,当您使用<button></button>放置按钮时,浏览器的行为会有所不同;单击它时,在调用事件处理程序后,它会重新加载页面,这就是为什么你应该在代码之后放置alert("")以防止页面重新加载。

您只需使用<input type="button" value="something">代替<button></button>即可阻止浏览器重新加载页面。

答案 9 :(得分:-2)

我遇到了同样的问题,只是添加了:

    <?php
    usleep(200000)// 2 seconds

?&gt;

之后的javascript(顺便说一句,需要将jQuery 1.9.1推迟到头部