我正在开发一个由使用Python的CherryPy框架编写的restful API驱动的Web应用程序。我开始用jQuery和服务器端模板的组合编写用户界面,但最终切换到Backbone.js,因为jQuery失控。
不幸的是,我在让我的模型与服务器同步时遇到了一些问题。以下是我的代码中的一个简单示例:
$(function() {
var User = Backbone.Model.extend({
defaults: {
id: null,
username: null,
token: null,
token_expires: null,
created: null
},
url: function() {
return '/api/users';
},
parse: function(response, options) {
console.log(response.id);
console.log(response.username);
console.log(response.token);
console.log(response.created);
return response;
}
});
var u = new User();
u.save({'username':'asdf', 'token':'asdf'}, {
wait: true,
success: function(model, response) {
console.log(model.get('id'));
console.log(model.get('username'));
console.log(model.get('token'));
console.log(model.get('created'));
}
});
});
正如您可能知道的,这里的想法是使用该服务注册新用户。当我调用u.save();
时,Backbone确实向服务器发送了POST请求。以下是相关内容:
请求:
Request URL: http://localhost:8080/api/users
Request Method: POST
Request Body: {"username":"asdf","token":"asdf","id":null,"token_expires":null,"created":null}
响应:
Status Code: HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 109
Response Body: {"username": "asdf", "created": "2013-02-07T13:11:09.811507", "token": null, "id": 14, "token_expires": null}
如您所见,服务器成功处理了请求,并发送了id
和created
的值。但由于某些原因,当我的代码调用console.log(u.id);
时,我得到null
,当我的代码调用console.log(u.created);
时,我得到undefined
。
tl; dr :为什么Backbone.js在调用save()
后不会对我的对象进行持续更改?
修改
我修改了上面的代码,以便使用success
回调中的get函数访问模型属性。这应解决原始代码的任何并发问题。
我还在模型的parse
函数中添加了一些控制台日志记录。奇怪的是,每个都是undefined
...这是否意味着Backbone.js无法解析我的响应JSON?
编辑2: 几天前,我发现该问题实际上是一个自定义标头,我添加到每个启用HTTP基本身份验证的请求。有关详细信息,请参阅this answer。
答案 0 :(得分:3)
此代码:
u.save();
console.log(u.id);
console.log(u.username);
console.log(u.token);
console.log(u.created);
立即运行......之后没有任何内容可以运行,排队的ajax请求开始了。然后响应稍晚,只有在那一点上改变了值。
似乎这些属性不是直接在对象上,但是保存的异步处理仍然存在,即使您将该代码更正为console.log(u.get("id"))
等,也无法获得预期的结果。 / p>
答案 1 :(得分:3)
我想出了这个问题,虽然我仍然无法解释为什么这是一个问题。我正在构建的Web应用程序具有身份验证过程,该过程需要与所有请求一起传递HTTP基本身份验证标头。
为了使用Backbone工作,我覆盖了Backbone.sync函数并更改了line 1398以添加标题。
原始代码:
var params = {type: type, dataType: 'json'};
修改后的代码:
var params = {
type: type,
dataType: 'json',
headers: {
'Authorization': getAuthHash()
}
};
函数getAuthHash()只返回表示相应身份验证信息的Base64字符串。
由于某种原因,添加此标头会导致同步/保存功能失败。如果我把它拿出来,一切都按照你的预期运作。
赏金仍然是开放的,我很乐意将奖励给任何可以解释原因的人,并为问题提供解决方案。
修改强>
看起来问题是我在请求中添加标头的方式。有一个很好的小JavaScript库available on Github通过正确添加HTTP Basic Auth标头来解决这个问题。
答案 2 :(得分:2)
我已经测试了你的代码,它对我来说很好。
在此处查看演示,jsfiddle.net/yxkUD/
答案 3 :(得分:1)
尝试将自定义的beforeSend方法添加到ajax请求以添加自定义标头。
例如: https://github.com/documentcloud/backbone/blob/master/backbone.js#L1424