我有一个服务器端功能,需要登录。如果用户登录成功,函数将返回1。如果不是,该函数将返回登录页面。

我想使用Ajax和jQuery调用该函数。我所做的是提交带有普通链接的请求,并在其上应用了单击功能。如果用户没有登录或函数失败,我希望ajax调用返回true,以便触发href。

但是,当我使用下面的代码时,函数在Ajax调用完成之前退出。

如何将用户优雅地重定向到登录页面?

$(".my_link").click(
    function(){
    $.ajax({
        url: $(this).attr('href'),
        type: 'GET',
        cache: false,
        timeout: 30000,
        error: function(){
            return true;
        },
        success: function(msg){ 
            if (parseFloat(msg)){
                return false;
            } else {
                return true;
            }
        }
    });
});

当前回答

它应该等待get请求完成。之后,我将从函数调用的地方返回get请求体。

function foo() {
    var jqXHR = $.ajax({
        url: url,
        type: 'GET',
        async: false,
    });
    return JSON.parse(jqXHR.responseText);  
}

其他回答

在现代JS中,你可以简单地使用async/await,比如:

  async function upload() {
    return new Promise((resolve, reject) => {
        $.ajax({
            url: $(this).attr('href'),
            type: 'GET',
            timeout: 30000,
            success: (response) => {
                resolve(response);
            },
            error: (response) => {
                reject(response);
            }
        })
    })
}

然后在一个异步函数中调用它,比如:

let response = await upload();

底层的XMLHttpRequest对象(由jQuery用于发出请求)支持 异步属性。设置为false。就像

async: false

因为async ajax是不赞成的,尝试使用带有承诺的嵌套async函数。可能有语法错误。


async function fetch_my_data(_url, _dat) {

   async function promised_fetch(_url, _dat) {

      return new Promise((resolve, reject) => {
         $.ajax({
            url:  _url,
            data: _dat,
            type: 'POST',
            success: (response) => {
               resolve(JSON.parse(response));
            },
            error: (response) => {
               reject(response);
            }
         });
      });
   }

   var _data = await promised_fetch(_url, _dat);
   
   return _data;
}

var _my_data = fetch_my_data('server.php', 'get_my_data=1');

最初的问题是在12年前的今天提出的,当时的问题是“如何让jQuery在返回之前等待Ajax调用完成?”从那时起,jQuery已经走过了很长的一段路。

上面提到了一些解决方案,但我无法让它们中的任何一个与最新版本的jQuery一起工作:$.when().then.()似乎不是同步的,除非它使用'async: false',这是不再支持的,所以不能在新版本的jQuery中工作。

但是承诺是内置在jQuery ajax调用中,因此使ajax调用同步应该不是那么困难。

我使用命名空间的js函数,所以下面的例子就是这种格式。示例是自定义表单验证,它调用服务器验证用户输入是否试图复制现有项。

除非使用Babel,否则这段代码可能无法在IE或Legacy Edge中工作,但我倾向于阻止这些浏览器,因为微软不再支持它们。

///Namespace validate
check: async function(settings){
    let IsValid = false;
    let Message = ''
    let data = await validate.serverCheck('function', value);
    IsValid = data.OK;
    Message = data.Message;
}

serverCheck: async function (fn, value) {
    var request = {
        validateValue: $.sanitize(value)
    };

    let result;

    try {
            result = await $.ajax({
                dataType: "json",
                type: "post",
                url: "/api/validate/" + fn + "/",
                data: request
        });

        return result;
    } catch (x) {}
}

结果出来了

我没有使用$。Ajax和$。Post和$。get函数,所以如果我需要等待响应,我使用这个:

$.ajaxSetup({async: false});
$.get("...");