【问题标题】:How to make JQuery-AJAX request synchronous如何使 JQuery-AJAX 请求同步
【发布时间】:2012-12-07 22:47:10
【问题描述】:

如何使 ajax 请求同步?

我有一个表格需要提交。但只有在用户输入正确密码时才需要提交。

表格代码如下:

<form name="form" action="insert.php" method="post" onSubmit="return ajaxSubmit(this);" >

发送和检查密码的jquery代码是这样的:

var ajaxSubmit = function(formE1) {

    var password = $.trim($('#employee_password').val());

    $.ajax({
        type: "POST",
        async: "false",
        url: "checkpass.php",
        data: "password="+password,
        success: function(html) {
            var arr=$.parseJSON(html);
            if(arr == "Successful") {
                return true;
            } else {
                return false;
            }
        }
    });
}

但是,无论 ajax 请求返回的值如何,表单总是提交。我已经检查了其他所有内容。当输入正确的密码时,arr 的值会显示为“成功”,反之亦然。

如何使这个请求同步?据我调试,请求是异步的,所以表单在请求完成之前被提交。

checkpass.php 的代码

<?php 
require("includes/apptop.php");
require("classes/class_employee.php");
require("classes/class_employee_attendance.php");

$employee_password=$_POST['password']; 

$m=new employee();
$m->setbyid_employee(1);
$arr=$m->editdisplay_employee();

if($arr['employee_password'] == $employee_password)
{
$res="Successful";  
}
else
{
$res="Password not match";  
}

echo $res;
?>

更新:已找到解决方案。

正如 Olaf Dietshche 所指出的:ajaxSubmit 的返回值不是success: function(){...} 的返回值。 ajaxSubmit 根本不返回任何值,这等价于 undefined,而后者的计算结果为 true

这就是为什么表单总是被提交并且独立于是否同步发送请求的原因。

所以,我在成功时将一个变量设置为 1 内的成功函数。并在success函数外检查它的值,如果在success函数外是1,那么我写return true ... else return false。这很有效。

更新的工作代码:

var ajaxsubmit=function(forme1) {
    var password = $.trim($('#employee_password').val());
    var test="0";

    $.ajax({
        type: "POST",
        url: "checkpass.php",
        async: false,
        data: "password="+password,
        success: function(html) {
            if(html == "Successful") {
                test="1";
            } else {
                alert("Password incorrect. Please enter correct password.");
                test="0";
            }
        }
    });

    if(test=="1") {
        return true;
    } else if(test=="0") {
        return false;
    }
}

【问题讨论】:

  • 你的服务器响应的数据类型是什么......json or html ??
  • 您可以通过按钮点击事件调用ajax并在提交时删除表单并在成功事件时使用表单提交功能。
  • @bipen: 我的服务器响应的数据类型是html only
  • @Dinesh:是的,我知道可以这样做。但我不想诉诸于此。有什么方法只能通过这种方式来实现?
  • thn 为什么你使用$.parseJSON(html);...pareseJson 采用格式良好的“JSON”字符串并返回生成的 JavaScript 对象...检查你的萤火虫这给了console.log(html)跨度>

标签: jquery ajax synchronous


【解决方案1】:

来自jQuery.ajax()

异步布尔
默认值:真
默认情况下,所有请求都是异步发送的(即默认设置为 true)。如果您需要同步请求,请将此选项设置为 false。

所以在您的请求中,您必须使用async: false 而不是async: "false"

更新

ajaxSubmit 的返回值不是success: function(){...} 的返回值。 ajaxSubmit 根本不返回任何值,相当于 undefined,其结果为 true。

是为什么表单总是被提交并且独立于发送请求是否同步的原因。

如果您只想提交表单,当响应为"Successful" 时,您必须从ajaxSubmit 返回false,然后按照@halilb 的建议在success 函数中提交表单。

按照这些思路应该可以工作

function ajaxSubmit() {
    var password = $.trim($('#employee_password').val());
    $.ajax({
        type: "POST",
        url: "checkpass.php",
        data: "password="+password,
        success: function(response) {
            if(response == "Successful")
            {
                $('form').removeAttr('onsubmit'); // prevent endless loop
                $('form').submit();
            }
        }
    });

    return false;
}

【讨论】:

  • 这已从最新版本的 jQuery 中删除。
  • @Archer 来自手册:“不推荐使用 jqXHR ($.Deferred) 的 false”。
  • 在执行此操作时,提交按钮显示为已单击并且页面挂起。也许表单会一次又一次地提交。当我在成功的情况下向内部发出警报时,它会一次又一次地发出警报。递归。
  • @user1865933 好的,我错过了。当从success 函数提交表单时,再次调用ajaxSubmit。但是,删除 onsubmit 属性应该可以防止这种情况发生。请重试。
  • @Olaf Dietsche:你是正确的。成功后,我在成功函数中将变量设置为 1。并从成功函数中检查它的值,如果它在成功函数之外是 1,那么我写了'return true',否则写'return false'。这奏效了。非常感谢:)
【解决方案2】:

它就像下面的一样简单,并且像一个魅力一样工作。

我的解决方案完美回答了你的问题:如何使 JQuery-AJAX 请求同步

在 ajax 调用之前将 ajax 设置为同步,然后在 ajax 调用之后将其重置:

$.ajaxSetup({async: false});

$ajax({ajax call....});

$.ajaxSetup({async: true});

在你的情况下,它看起来像这样:

$.ajaxSetup({async: false});

$.ajax({
        type: "POST",
        async: "false",
        url: "checkpass.php",
        data: "password="+password,
        success: function(html) {
            var arr=$.parseJSON(html);
            if(arr == "Successful") {
                return true;
            } else {
                return false;
            }
        }
    });


$.ajaxSetup({async: true});

希望对你有帮助:)

【讨论】:

  • 虽然这是为 AJAX 调用设置默认参数的便捷方式,但它完全忽略了实际错误并导致不必要的解决方法。 async 参数采用布尔值,而不是字符串。将其更改为布尔值是解决方案。
【解决方案3】:

您可以阻止提交按钮的默认操作,而不是添加 onSubmit 事件。

所以,在下面的 html 中:

<form name="form" action="insert.php" method="post">
    <input type='submit' />
</form>​

首先,防止提交按钮动作。然后异步调用ajax,密码正确后提交表单。

$('input[type=submit]').click(function(e) {
    e.preventDefault(); //prevent form submit when button is clicked

    var password = $.trim($('#employee_password').val());

     $.ajax({
        type: "POST",
        url: "checkpass.php",
        data: "password="+password,
        success: function(html) {
            var arr=$.parseJSON(html);
            var $form = $('form');
            if(arr == "Successful")
            {    
                $form.submit(); //submit the form if the password is correct
            }
        }
    });
});​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

【讨论】:

  • @halib:上述方法有效。我试过了。但我不想诉诸这种方式。我们不能通过默认的 onsubmit 事件来实现这一点吗?
【解决方案4】:

我将dataType添加为json并将响应作为json:

PHP

echo json_encode(array('success'=>$res)); //send the response as json **use this instead of echo $res in your php file**

JavaScript

  var ajaxSubmit = function(formE1) {

        var password = $.trim($('#employee_password').val());    
        $.ajax({
            type: "POST",
            async: "false",
            url: "checkpass.php",
            data: "password="+password,
            dataType:'json',  //added this so the response is in json
            success: function(result) {
                var arr=result.success;
                if(arr == "Successful")
                {    return true;
                }
                else
                {    return false;
                }
            }
        });

  return false
}

【讨论】:

  • async 参数采用布尔值,而不是字符串。字符串"false" 实际上被强制转换为true,因为字符串不为空。
【解决方案5】:

试试这个

解决方案是,使用这样的回调

$(function() {

    var jForm = $('form[name=form]');
    var jPWField = $('#employee_password');

    function getCheckedState() {
        return jForm.data('checked_state');
    };

    function setChecked(s) {
        jForm.data('checked_state', s);
    };


    jPWField.change(function() {
        //reset checked thing
        setChecked(null);
    }).trigger('change');

    jForm.submit(function(){
        switch(getCheckedState()) {
            case 'valid':
                return true;
            case 'invalid':
                //invalid, don submit
                return false;
            default:
                //make your check
                var password = $.trim(jPWField.val());

                $.ajax({
                    type: "POST",
                    async: "false",
                    url: "checkpass.php",
                    data: {
                        "password": $.trim(jPWField.val);
                    }
                    success: function(html) {
                        var arr=$.parseJSON(html);
                        setChecked(arr == "Successful" ? 'valid': 'invalid');
                        //submit again
                        jForm.submit();
                    }
                    });
                return false;
        }

    });
 });

【讨论】:

    【解决方案6】:

    你可以试试这个,

    var ajaxSubmit = function(formE1) {
    
                var password = $.trim($('#employee_password').val());
    
                 $.ajax({
                    type: "POST",
                    async: "false",
                    url: "checkpass.php",
                    data: "password="+password,
                    success: function(html) {
                        var arr=$.parseJSON(html);
                        if(arr == "Successful")
                        { 
                             **$("form[name='form']").submit();**
                            return true;
                        }
                        else
                        {    return false;
                        }
                    }
                });
                  **return false;**
            }
    

    【讨论】:

    • 当然。我会检查并在一分钟内通知您
    • 只有在密码错误的情况下才有效。输入当前密码后,提交按钮仍处于单击状态。页面停止响应
    • 我希望你删除代码中的**。你能在成功的情况下提醒吗?
    • 是的,我在代码中删除了**。当我将警报代码放入成功的 if 块时,警报出现了,但它总是一次又一次地出现。单击确定后,它会再次显示,依此类推。递归地。也许表单会一次又一次地提交
    • 好的,出于测试目的,您可以从代码中删除 async: "false" 并使用 exit();在 php 文件的末尾。
    【解决方案7】:

    以下是一个工作示例。添加async:false

    const response = $.ajax({
                        type:"POST",
                        dataType:"json",
                        async:false, 
                        url:"your-url",
                        data:{"data":"data"}                        
                    });                   
     console.log("response: ", response);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-11
      • 2011-10-04
      • 1970-01-01
      • 2016-02-13
      • 2011-08-14
      • 2016-10-22
      相关资源
      最近更新 更多