向Backbone.js添加HTTP基本身份验证标头同步功能可防止在Save()上更新模型

Mus*_*ice 5 javascript cherrypy basic-authentication http-headers backbone.js

我正在开发一个Web应用程序,它由一个用Python的CherryPy框架编写的restful API提供支持.我开始用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'));
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

您可能会说,这里的想法是使用该服务注册新用户.当我打电话时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}
Run Code Online (Sandbox Code Playgroud)

响应:

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}
Run Code Online (Sandbox Code Playgroud)

如您所见,服务器成功处理请求并发回一个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基本身份验证的请求.有关详情,请参阅此答案.

Mus*_*ice 3

我弄清楚了这个问题,尽管我仍然无法解释为什么这是一个问题。我正在构建的 Web 应用程序有一个身份验证过程,需要与所有请求一起传递 HTTP 基本身份验证标头。

为了使其与 Backbone 一起工作,我覆盖了 Backbone.sync 函数并更改了第 1398 行以添加标头。

原始代码:

var params = {type: type, dataType: 'json'};
Run Code Online (Sandbox Code Playgroud)

修改后的代码:

var params = {
    type: type,
    dataType: 'json',
    headers: {
        'Authorization': getAuthHash()
    }
};
Run Code Online (Sandbox Code Playgroud)

函数 getAuthHash() 仅返回表示适当身份验证信息的 Base64 字符串。

由于某种原因,添加此标头会使同步/保存功能失败。如果我把它拿出来,一切都会如你所期望的那样进行。

赏金仍然开放,我很乐意将其奖励给任何能够解释其原因并提供问题解决方案的人。

编辑:

看起来问题在于我将标头添加到请求的方式。Github 上有一个不错的小型 JavaScript 库,它通过正确添加 HTTP Basic Auth 标头来解决这个问题。