Re-call Backbone.Sync 错误回调后的方法
Re-call Backbone.Sync method after error callback
我正在开发一个应用程序,如果我们的 Bearer 令牌已过期并且我们从服务器返回 401。我们想调用一个端点 /api/newToken
并将新的承载令牌设置为 cookie(稍后添加到 headers),然后重新调用错误时调用的 URL (401 状态)发生。
我们覆盖了 backbone 同步方法
var sync_mixin = {
// `preSync` is a useful hook from which events can be published,
// and options / model may be modified.
preSync: function (method, model, options) {},
// override sync to:
// - call preSync first
// - because tastypie and backbone disagree on whether delete should have trailing slash
sync: function (method, model, options) {
model.preSync(method, model, options);
options = options || {};
options.headers = getAuthHeaders()
// Add trailing slash to backbone model views
var _url = _.isFunction(model.url) ? model.url() : model.url;
// Missing the case where there is a query string on a detail view here: /v7.0/<resource>/<id>?key=val
_url += _url.charAt(_url.length - 1) == '/' || _url.indexOf('?') != -1 ? '' : '/';
options = _.extend(options, {
url: _url,
model: model
});
if (method.toLowerCase() === 'delete') {
if (!options.url) {
options.url = _.result(model, 'url').replace(/\/$/, "") + '/';
}
}
return Backbone.sync.apply(this, arguments);
}
};
Backbone.Model = Backbone.Model.extend(sync_mixin);
理想情况下,我想在一个地方处理错误(而不是在每个模型文件中)。我想要完成的是当我收到同步错误时,调用 api 端点获取新令牌,将其设置为 cookie 并使用新 cookie 作为令牌重新调用原始同步方法。这是我尝试过的方法,但我 运行 遇到最大调用堆栈错误。我在上面的同步函数中添加了这段代码
options.error = function(xhr, status, thrown) {
if(xhr.status === 401 || xhr.status === 403){
$.cookies.set("auth-token", '6fe36b69cdac549339850a5aa2f148b470dc2e0e');
Backbone.sync.apply(this.model, arguments);
}
}
关于如何解决这个问题有什么建议吗?我可以得到任何其他需要的东西。
我成功了。 Tte 最大调用堆栈错误是由于我不小心将请求添加回进行递归调用的选项。
这是我允许调用同步的代码
var errorHandler = options.error;
options.error = function(xhr) {
var errorHandlerArgs = arguments;
if ((xhr.status === 401 || xhr.status === 0) && $this.ajaxTried < 3) {
$this.ajaxTried++;
//call refresh_bearer/ URL
$.ajax({
url: "/api/refresh_bearer/",
headers: args[2].headers
}).done(function (data) {
args[2].headers = getAuthHeaders()
Backbone.sync.apply($this, args);
});
} else {
$this.ajaxTried = 0;
errorHandler.apply($this, errorHandlerArgs);
}
};
我正在开发一个应用程序,如果我们的 Bearer 令牌已过期并且我们从服务器返回 401。我们想调用一个端点 /api/newToken
并将新的承载令牌设置为 cookie(稍后添加到 headers),然后重新调用错误时调用的 URL (401 状态)发生。
我们覆盖了 backbone 同步方法
var sync_mixin = {
// `preSync` is a useful hook from which events can be published,
// and options / model may be modified.
preSync: function (method, model, options) {},
// override sync to:
// - call preSync first
// - because tastypie and backbone disagree on whether delete should have trailing slash
sync: function (method, model, options) {
model.preSync(method, model, options);
options = options || {};
options.headers = getAuthHeaders()
// Add trailing slash to backbone model views
var _url = _.isFunction(model.url) ? model.url() : model.url;
// Missing the case where there is a query string on a detail view here: /v7.0/<resource>/<id>?key=val
_url += _url.charAt(_url.length - 1) == '/' || _url.indexOf('?') != -1 ? '' : '/';
options = _.extend(options, {
url: _url,
model: model
});
if (method.toLowerCase() === 'delete') {
if (!options.url) {
options.url = _.result(model, 'url').replace(/\/$/, "") + '/';
}
}
return Backbone.sync.apply(this, arguments);
}
};
Backbone.Model = Backbone.Model.extend(sync_mixin);
理想情况下,我想在一个地方处理错误(而不是在每个模型文件中)。我想要完成的是当我收到同步错误时,调用 api 端点获取新令牌,将其设置为 cookie 并使用新 cookie 作为令牌重新调用原始同步方法。这是我尝试过的方法,但我 运行 遇到最大调用堆栈错误。我在上面的同步函数中添加了这段代码
options.error = function(xhr, status, thrown) {
if(xhr.status === 401 || xhr.status === 403){
$.cookies.set("auth-token", '6fe36b69cdac549339850a5aa2f148b470dc2e0e');
Backbone.sync.apply(this.model, arguments);
}
}
关于如何解决这个问题有什么建议吗?我可以得到任何其他需要的东西。
我成功了。 Tte 最大调用堆栈错误是由于我不小心将请求添加回进行递归调用的选项。
这是我允许调用同步的代码
var errorHandler = options.error;
options.error = function(xhr) {
var errorHandlerArgs = arguments;
if ((xhr.status === 401 || xhr.status === 0) && $this.ajaxTried < 3) {
$this.ajaxTried++;
//call refresh_bearer/ URL
$.ajax({
url: "/api/refresh_bearer/",
headers: args[2].headers
}).done(function (data) {
args[2].headers = getAuthHeaders()
Backbone.sync.apply($this, args);
});
} else {
$this.ajaxTried = 0;
errorHandler.apply($this, errorHandlerArgs);
}
};