一時的な理由で失敗した ajax リクエストを再試行するシステムを実装しようとしています。私の場合、セッションを復活させる更新 Web サービスを呼び出した後、セッションの有効期限が切れたために 401 ステータス コードで失敗した要求を再試行することです。
問題は、呼び出される「成功」ajax オプション コールバックとは異なり、「完了」コールバックが成功した再試行で呼び出されないことです。以下に簡単な例を作成しました。
$.ajaxSetup({statusCode: {
404: function() {
this.url = '/existent_url';
$.ajax(this);
}
}});
$.ajax({
url: '/inexistent_url',
success: function() { alert('success'); }
})
.done(function() {
alert('done');
});
再試行が成功したときに完了スタイルのコールバックを呼び出す方法はありますか? 遅延が「拒否」された後に「解決」できないことはわかっていますが、拒否を防ぐことは可能ですか? それとも、元の deferred の doneList を新しい deferred にコピーするのでしょうか? 私はアイデアがありません:)
以下のより現実的な例では、401 で拒否されたすべての要求をキューに入れ、/refresh の呼び出しが成功した後に再試行します。
var refreshRequest = null,
waitingRequests = null;
var expiredTokenHandler = function(xhr, textStatus, errorThrown) {
//only the first rejected request will fire up the /refresh call
if(!refreshRequest) {
waitingRequests = $.Deferred();
refreshRequest = $.ajax({
url: '/refresh',
success: function(data) {
// session refreshed, good
refreshRequest = null;
waitingRequests.resolve();
},
error: function(data) {
// session can't be saved
waitingRequests.reject();
alert('Your session has expired. Sorry.');
}
});
}
// put the current request into the waiting queue
(function(request) {
waitingRequests.done(function() {
// retry the request
$.ajax(request);
});
})(this);
}
$.ajaxSetup({statusCode: {
401: expiredTokenHandler
}});
このメカニズムは機能し、401 で失敗したリクエストが 2 度目に起動されます。問題は、「完了」コールバックが呼び出されないため、アプリケーションが停止することです。