August
4th,
2013
问题代码
最近有那么一段 js 代码,困扰了很久很久,开发环境又是 PhoneGap,所以没办法调试 js…
代码大致逻辑如下:
var options
options.error = function (model, xhr, options) {
if (xhr.status === 401) {
//todo: login
Backbone.sync(method, model, options)
return
}
}
options.success = function (model, xhr, options) {
//todo:
}
Backbone.sync(method, model, options)
逻辑很简单,就是如果登陆的时候返回401错误,就重新登陆一下,登陆完成后重新请求数据。
这段代码没有问题,但是这个逻辑 + zepto + backbone 就有问题了。
代码在第二次请求的时候,就会报一个错误: xhr 是一个对象而不是一个函数。
问题根源
看了一下 backbone 和 zepto 的源代码后,发现了这个问题的根源!
backbone 会把请求的 xhr 对象赋值到传入的 options 对象上,所以第二次请求的 options 对象上会有一个 xhr 对象。
而 zepto 在收到 options 的时候,会判断是否有 xhr ,如果没有的话,就设置一个默认的函数,内部逻辑是:new window.XMLHttpRequest()
。
这就是为什么会报那个错误啦。
解决办法
解决办法其实也非常简单啦,在第二次调用的时候把 options 里的 xhr 对象删除即可。
options.error = function (model, xhr, options) {
if (xhr.status === 401) {
//todo: login
delete options.xhr
Backbone.sync(method, model, options)
return
}
}
本作品由 Dozer 创作,采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。