我有多个ajax请求,每分钟都会有一些请求数据由用户通过ui启动。
$.get('/myurl', data).done(function( data ){
// do stuff..
});
由于身份验证失败,请求可能会失败。
我已经设置了一个全局.ajaxError()
方法来捕获任何失败的请求。
$(document).ajaxError(function( e, jqxhr ){
// Correct error..
});
我发现错误后重置授权。 重置授权有效,但用户必须手动重新启动ajax调用(通过ui)。
如何使用最初发送的jqxhr重新发送失败的请求?
(我正在使用jQuery for ajax)
答案 0 :(得分:11)
发现this post表明这个问题的解决方案很好。
最重要的是使用$.ajaxPrefilter并将错误处理程序替换为自定义的错误处理程序,以检查重试并使用闭包的'originalOptions'执行重试。
我发布的代码是为了防止将来离线。此信用额度归属于the original author。
// register AJAX prefilter : options, original options
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
originalOptions._error = originalOptions.error;
// overwrite error handler for current request
options.error = function( _jqXHR, _textStatus, _errorThrown ){
if (... it should not retry ...){
if( originalOptions._error ) originalOptions._error( _jqXHR, _textStatus, _errorThrown );
return;
};
// else... Call AJAX again with original options
$.ajax( originalOptions);
};
});
答案 1 :(得分:7)
在这种情况下,我会为403
状态代码编写一个特定的处理程序,这意味着未经授权(我的服务器也将返回403)。从jquery ajax docs,你可以做到
$.ajax({
statusCode: {
403: function() {
relogin(onSuccess);
}
}
});
实现这一点。
在该处理程序中,我将调用relogin
方法,传递一个捕获登录成功时要执行的操作的函数。在这种情况下,您可以传入包含要再次运行的调用的方法。
在上面的代码中,relogin
应该调用登录代码,onSuccess
应该是一个包装你每分钟执行的代码的函数。
编辑 - 基于您在评论中的澄清,这种情况发生在多个请求中,我个人会为您的应用创建一个API,用于捕获与服务器的交互。
app = {};
app.api = {};
// now define all your requests AND request callbacks, that way you can reuse them
app.api.makeRequest1 = function(..){..} // make request 1
app.api._request1Success = function(...){...}// success handler for request 1
app.api._request1Fail = function(...){...}// general fail handler for request 1
/**
A method that will construct a function that is intended to be executed
on auth failure.
@param attempted The method you were trying to execute
@param args The args you want to pass to the method on retry
@return function A function that will retry the attempted method
**/
app.api.generalAuthFail = function(attempted, args){
return function(paramsForFail){ // whatever jquery returns on fail should be the args
if (attempted) attempted(args);
}
}
因此,使用该结构,您可以在request1
方法中执行类似
$().ajax({
....
statusCode: {
403: app.api.generalAuthFail(app.api.request1, someArgs);
}
}}
generalAuthFailure
将返回执行您传入的方法的回调。
答案 2 :(得分:2)
以下代码将保留原始请求,并将尝试成功3次。
var tries = 0;
$( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
if(tries < 3){
tries++;
$.ajax(this).done(function(){tries=0;});
}
});
答案 3 :(得分:0)
您可以选择为每个函数命名,然后按照hvgotcodes的答案中的说明调用它们。
或者
您可以使用可重复使用的功能在扩展默认值时设置请求:
function getRequest( options ){
var // always get json
defaults = { dataType: 'json' },
settings = $.extend( defaults, options );
return // send initial ajax, if it's all good return the jqxhr object
$.ajax( settings )
// on error
.fail(function( jqxhr, e ){
// if the users autherization has failed out server responds with a 401
if( jqxhr.status === 401 ){
// Authenticate user again
resetAuthentication()
.done(function(){
// resend original ajax also triggering initial callback
$.ajax( settings );
});
}
});
};
要使用上述功能,您可以这样写:
getRequest({
url: 'http://www.example.com/auth.php',
data: {user: 'Mike', pass: '12345'},
success: function(){ // do stuff }
});
getRequest()
可能会被递归和/或转换为jQuery插件,但这足以满足我的需求。
注意: 如果resetAutentication函数可能失效,getRequest()
必须是递归的。