我有一个服务器端功能,需要登录。如果用户登录成功,函数将返回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;
}
}
});
});
在现代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();
如果你不想让$.ajax()函数立即返回,将async选项设置为false:
$(".my_link").click(
function(){
$.ajax({
url: $(this).attr('href'),
type: 'GET',
async: false,
cache: false,
timeout: 30000,
fail: function(){
return true;
},
done: function(msg){
if (parseFloat(msg)){
return false;
} else {
return true;
}
}
});
});
但是,我要指出,这与AJAX的观点是相反的。此外,您应该在fail和done函数中处理响应。只有当从服务器接收到响应时,才会调用这些函数。
最初的问题是在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) {}
}
结果出来了
在现代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();