您可以
jQuery.ajaxPrefilter用来将jqXHR包装在另一个延迟的对象中。
我在上面的示例
jsFiddle中显示了它的工作原理,并尝试调整您的一些代码以将401处理到此版本中:
$.ajaxPrefilter(function(opts, originalOpts, jqXHR) { // you could pass this option in on a "retry" so that it doesn't // get all recursive on you. if (opts.refreshRequest) { return; } // our own deferred object to handle done/fail callbacks var dfd = $.Deferred(); // if the request works, return normally jqXHR.done(dfd.resolve); // if the request fails, do something else // yet still resolve jqXHR.fail(function() { var args = Array.prototype.slice.call(arguments); if (jqXHR.status === 401) { $.ajax({ url: '/refresh', refreshRequest: true, error: function() { // session can't be saved alert('Your session has expired. Sorry.'); // reject with the original 401 data dfd.rejectWith(jqXHR, args); }, success: function() { // retry with a copied originalOpts with refreshRequest. var newOpts = $.extend({}, originalOpts, { refreshRequest: true }); // pass this one on to our deferred pass or fail. $.ajax(newOpts).then(dfd.resolve, dfd.reject); } }); } else { dfd.rejectWith(jqXHR, args); } }); // NOW override the jqXHR's promise functions with our deferred return dfd.promise(jqXHR);});之所以有效,是因为
deferred.promise(object)它将实际上覆盖jqXHR上的所有“承诺方法”。
注意: 对于任何其他发现此问题的人,如果您在ajax选项中使用
success:和附加回调
error:,则此代码段将 无法
按您期望的方式工作。假定唯一的回调是使用jqXHR 的
.done(callback)和
.fail(callback)方法附加的回调。



