如何重新发送失败的ajax请求?

我有多个ajax请求,每分钟一些请求数据由用户通过ui启动。

$.get('/myurl', data).done(function( data ){ // do stuff.. }); 

由于身份validation失败,请求可能会失败。 我已经设置了一个全局的.ajaxError()方法来捕获任何失败的请求。

 $(document).ajaxError(function( e, jqxhr ){ // Correct error.. }); 

在我发现错误后,我重置了授权。 重置授权有效,但用户必须手动重新启动ajax调用(通过ui)。

如何使用最初发送的jqxhr重新发送失败的请求?

(我正在使用jQuery for ajax)

发现这篇文章提出了解决这个问题的好方法

主要的是使用$ .ajaxPrefilter并使用自定义的error handling程序替换您的error handling程序,该自定义程序检查重试并使用闭包的’originalOptions’执行重试。

我发布代码以防万一它将来会离线,再次,信用属于原作者

 // 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); }; }); 

在这种情况下,我会为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将返回一个执行您传入的方法的回调。

下面的代码将保留原始请求,它将尝试成功3次。

 var tries = 0; $( document ).ajaxError(function( event, jqxhr, settings, thrownError ) { if(tries < 3){ tries++; $.ajax(this).done(function(){tries=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()必须是递归的。