我有一个服务器端功能,需要登录。如果用户登录成功,函数将返回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;
            }
        }
    });
});

当前回答

因为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');

其他回答

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

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

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

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

我认为,如果您将成功函数编码为加载适当的页面,而不是返回true或false,事情就会更容易。

例如,你可以这样做,而不是返回true:

window.location="appropriate page";

这样,当成功函数被调用时,页面被重定向。

因为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');

与其将async设置为false(这通常是糟糕的设计),不如考虑在操作挂起时阻塞UI。

这可以很好地实现jQuery承诺如下:

// same as $.ajax but settings can have a maskUI property
// if settings.maskUI==true, the UI will be blocked while ajax in progress
// if settings.maskUI is other than true, it's value will be used as the color value while bloking (i.e settings.maskUI='rgba(176,176,176,0.7)'
// in addition an hourglass is displayed while ajax in progress
function ajaxMaskUI(settings) {
    function maskPageOn(color) { // color can be ie. 'rgba(176,176,176,0.7)' or 'transparent'
        var div = $('#maskPageDiv');
        if (div.length === 0) {
            $(document.body).append('<div id="maskPageDiv" style="position:fixed;width:100%;height:100%;left:0;top:0;display:none"></div>'); // create it
            div = $('#maskPageDiv');
        }
        if (div.length !== 0) {
            div[0].style.zIndex = 2147483647;
            div[0].style.backgroundColor=color;
            div[0].style.display = 'inline';
        }
    }
    function maskPageOff() {
        var div = $('#maskPageDiv');
        if (div.length !== 0) {
            div[0].style.display = 'none';
            div[0].style.zIndex = 'auto';
        }
    }
    function hourglassOn() {
        if ($('style:contains("html.hourGlass")').length < 1) $('<style>').text('html.hourGlass, html.hourGlass * { cursor: wait !important; }').appendTo('head');
        $('html').addClass('hourGlass');
    }
    function hourglassOff() {
        $('html').removeClass('hourGlass');
    }

    if (settings.maskUI===true) settings.maskUI='transparent';

    if (!!settings.maskUI) {
        maskPageOn(settings.maskUI);
        hourglassOn();
    }

    var dfd = new $.Deferred();
    $.ajax(settings)
        .fail(function(jqXHR, textStatus, errorThrown) {
            if (!!settings.maskUI) {
                maskPageOff();
                hourglassOff();
            }
            dfd.reject(jqXHR, textStatus, errorThrown);
        }).done(function(data, textStatus, jqXHR) {
            if (!!settings.maskUI) {
                maskPageOff();
                hourglassOff();
            }
            dfd.resolve(data, textStatus, jqXHR);
        });

    return dfd.promise();
}

有了这个,你现在可以做:

ajaxMaskUI({
    url: url,
    maskUI: true // or try for example 'rgba(176,176,176,0.7)'
}).fail(function (jqXHR, textStatus, errorThrown) {
    console.log('error ' + textStatus);
}).done(function (data, textStatus, jqXHR) {
    console.log('success ' + JSON.stringify(data));
});

UI将阻塞,直到ajax命令返回

见JSFIDDLE