在我的Backbone / Marionette应用程序的每个经过身份验证的请求(GET,POST等)中,我必须附加一个accessToken。
我将此accessToken和expireDate存储在localStorage中。
要检查accessToken是否过期,我调用此方法:user.checkToken()。 如果已过期,则该方法会使用POST请求将accessToken更新到我的后端。
我应该把这张支票放在哪里?我的意思是,申请的哪一部分?
我是否应该重写 Backbone.sync 方法或使用 ajax.setup “beforeSend”?
提前感谢您的建议/想法。
答案 0 :(得分:2)
覆盖模型的sync()
函数并执行您需要执行的任何操作。例如:
var MyModel = Backbone.Model.extend({
sync: function() {
// Put your code here
Backbone.Model.prototype.sync.apply(this, arguments);
}
});
编辑#1:
不知道从哪里得到user
(以及其他变量),但在这里:
var MyModel = Backbone.Model.extend({
sync: function() {
user.checkToken().done(_.bind(function(){
Backbone.Model.prototype.sync.apply(this, [ method, model, options ]);
});
}, this);
});
答案 1 :(得分:2)
Backbone使用jQuery(请参阅可能适用于Zepto的解决方案的注释)来获取ajax请求,因此您可以使用(如Edward所建议的)jQuery.ajaxPrefilter。
我为这项任务做了一点测试,让我知道是否有任何问题:
function tokenIsExpired() {
return true;
}
function createPromiseFunction(method, jqXHRsource, jqXHR) {
return function() {
jqXHRsource[method] = function(f) {
if (f) {
jqXHR[method] = function() {
f.apply(this, arguments);
};
}
return this;
};
}
}
function updateToken() {
return $.ajax({
url: '',
method: 'GET',
data: {some:'data', here:'yes'},
success: function() {
// update the token sir
console.log('token call done')
},
skipTokenCheck: true // required
});
}
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
/*
* check if token is expired every time a new ajax request is made
* if it is expired, aborts the current requests, updated the token
* and eventually does the original request again.
*/
if (!options.skipTokenCheck && tokenIsExpired()) {
// at this point no callback should have be added to the promise object
var methodsNames = [
'done',
'always',
'fail',
'progress',
'then'
];
var methods = {};
// copy the callbacks when they're added to the old request
for (var i = 0; i < methodsNames.length; i++) {
var name = methodsNames[i];
createPromiseFunction(name, jqXHR, methods)();
};
jqXHR.abort();
// TODO: error checks
updateToken().done(function() {
console.log('done');
var newReq = $.ajax($.extend(originalOptions, {skipTokenCheck: true}));
for (var i = 0; i < methodsNames.length; i++) {
var name = methodsNames[i];
var f = methods[name];
if (f) {
newReq[name](f);
}
};
});
}
});
var p = $.get('.');
p.done(function() { console.log(arguments); }).fail(function() {
console.log('fail');
});
看起来ajaxPrefilter不适用于Zepto。或者,您可以使用ajaxBeforeSend事件。
在beforeSend函数中返回false将取消请求。
应该很容易调整我上面发布的代码。