Backbone.js 捕获主干同步错误
我需要在服务器的所有响应中捕获一个可能的登录页面,因此我全局覆盖了Backbone.sync,以便在传递错误之前检查所有错误Backbone.js 捕获主干同步错误,backbone.js,jquery-deferred,Backbone.js,Jquery Deferred,我需要在服务器的所有响应中捕获一个可能的登录页面,因此我全局覆盖了Backbone.sync,以便在传递错误之前检查所有错误 Backbone.originalSync = Backbone.sync; Backbone.sync = function (method, model, options) { var originalSuccess, originalError; console.log("sync override..."); // remember or
Backbone.originalSync = Backbone.sync;
Backbone.sync = function (method, model, options) {
var originalSuccess, originalError;
console.log("sync override...");
// remember original success so we can call it if user logs in successfully
originalSuccess = options.success;
// proxy the error callback to first check if we get a login page back
originalError = options.error;
options.error = function (model, xhr, options) {
if (xhr.status === 200 && xhr.responseText === "") {
// parse error from empty response (jq1.9 invalid json, ok)
originalSuccess(model, xhr, options);
} else {
console.log("Sync error " + statusTxt + ", " + thrown.message);
if (xhr.status === 200 || xhr.status === 302 || xhr.status === 0) {
// login page returned instead of json...
// open a new window with relogon.html to trigger a new login
window.showModalDialog("../relogon.html");
} else {
// normal error, pass along
if (originalError) {
originalError(model, xhr, options);
}
}
}
};
// call the original sync
Backbone.originalSync(method, model, options);
};
当从0.9.9降到1.0时,这一点非常糟糕。看起来原始的Backbone.sync以不同的方式包装了它的错误处理程序,导致首先使用jquery xhr签名调用我的错误处理程序。
我必须将错误处理程序的签名更改为:
options.error = function (xhr, statusTxt, thrown) {
好吧,现在它起作用了,但我觉得我做错了什么
有更好的方法吗
我尝试使用jquery承诺,但我需要能够从错误状态切换到成功状态(当调用originalSuccess时),这似乎不适用于承诺 所有同步错误都会传递到模型的
error
事件,因此您可能需要收听此事件
发件人:
“error”(model、xhr、options)-当服务器上的模型保存调用失败时
要全局捕获错误,您可以使用您可以构建自己的jQuery来更改默认的
主干.sync
行为
Backbone.sync = function (method, model, opts) {
var xhr, dfd;
dfd = $.Deferred();
// opts.success and opts.error are resolved against the deferred object
// instead of the jqXHR object
if (opts)
dfd.then(opts.success, opts.error);
xhr = Backbone.originalSync(method, model, _.omit(opts, 'success', 'error'));
// success : forward to the deferred
xhr.done(dfd.resolve);
// failure : resolve or reject the deferred according to your cases
xhr.fail(function() {
if (xhr.status === 200 && xhr.responseText === "") {
dfd.resolve.apply(xhr, arguments);
} else {
if (xhr.status === 200 || xhr.status === 302 || xhr.status === 0) {
console.log('login');
}
dfd.reject.apply(xhr, arguments);
}
});
// return the promise to add callbacks if necessary
return dfd.promise();
};
承诺反映了你选择的最终状态
为了失败的演示,为了成功
如果可以的话
- 您可能不应该将主干网与登录处理绑定得如此紧密。按照@Andrey的建议,使用主干或
中的事件jQuery.ajaxError
- 您的服务器响应应该表明授权失败,可能是401状态
- 当您重写sync时,不要忘记返回延迟承诺/jqXHR对象,这可能会在将来派上用场