将 HTTP 基本身份验证标头添加到 Backbone.js 同步函数可防止模型在 Save() 时更新 [英] Adding HTTP Basic Authentication Header to Backbone.js Sync Function Prevents Model from Being Updated on Save()

查看:15
本文介绍了将 HTTP 基本身份验证标头添加到 Backbone.js 同步函数可防止模型在 Save() 时更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 Web 应用程序,该应用程序由使用 Python 的 CherryPy 框架编写的 Restful API 提供支持.我开始使用 jQuery 和服务器端模板的组合来编写用户界面,但最终切换到 Backbone.js,因为 jQuery 失控了.

I'm working on a web application that is powered by a restful API written with Python's CherryPy framework. I started out writing the user interface with a combination of jQuery and server side templates, but eventually switched to Backbone.js because the jQuery was getting out of hand.

不幸的是,我在让我的模型与服务器同步时遇到了一些问题.这是我的代码中的一个简单示例:

Unfortunately, I'm having some problems getting my models to sync with the server. Here's a quick example from my code:

$(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 请求.以下是相关位:

As you can probably tell, the idea here is to register a new user with the service. When I call u.save();, Backbone does indeed send a POST request to the server. Here are the relevant bits:

请求:

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}

如您所见,服务器成功处理了请求并返回一个 idcreated 的值.但是出于某种原因,当我的代码调用 console.log(u.id); 时,我得到 null,而当我的代码调用 console.log(u.created);,我得到 undefined.

As you can see, the server successfully processes the request and sends back an id and a value for created. But for some reason, when my code calls console.log(u.id);, I get null, and when my code calls console.log(u.created);, I get undefined.

tl;dr:为什么 Backbone.js 在调用 save() 后不将更改持久化到我的对象?

tl;dr: Why isn't Backbone.js persisting changes to my objects after a call to save()?

我修改了上面的代码,以便使用 success 回调中的 get 函数访问模型属性.这应该可以解决原始代码的任何并发问题.

I've modified the above code so that the model properties are accessed using the get function in a success callback. This should solve any concurrency problems with the original code.

我还在模型的 parse 函数中添加了一些控制台日志记录.奇怪的是,每一个都是 undefined...这是否意味着 Backbone.js 无法解析我的响应 JSON?

I've also added some console logging in the model's parse function. Oddly enough, each of these is undefined... Does that mean that Backbone.js is failing to parse my response JSON?

编辑 2:几天前,我发现问题实际上是一个自定义标头,我将它添加到每个请求中以启用 HTTP 基本身份验证.有关详细信息,请参阅此答案.

Edit 2: A few days ago, I found out that issue was actually a custom header that I was adding to every request to enable HTTP Basic Authentication. See this answer for details.

推荐答案

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

I figured out the issue, although I'm still at a loss to explain why it's an issue at all. The web app that I'm building has an authentication process that requires an HTTP basic Authentication header to be passed with all requests.

为了使这个与 Backbone 一起工作,我覆盖了 Backbone.sync 函数并更改了 第 1398 行 添加标题.

In order to make this work with Backbone, I overrode the Backbone.sync function and changed line 1398 to add the header.

原始代码:

var params = {type: type, dataType: 'json'};

修改后的代码:

var params = {
    type: type,
    dataType: 'json',
    headers: {
        'Authorization': getAuthHash()
    }
};

函数 getAuthHash() 只返回一个 Base64 字符串,表示适当的身份验证信息.

The function getAuthHash() just returns a Base64 string that represents the appropriate authentication information.

出于某种原因,添加此标头会使同步/保存功能失败.如果我把它拿出来,一切都会如你所愿.

For some reason, the addition of this header makes the sync/save functions fail. If I take it out, everything works as you might expect it to.

赏金仍然开放,我很乐意奖励任何可以解释原因并提供问题解决方案的人.

The bounty is still open, and I'll happily reward it to anybody who can explain why this is, as well as provide a solution to the problem.

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

It looks like the problem was the way that I was adding the header to the request. There's a nice little JavaScript library available on Github that solves this problem by correctly adding the HTTP Basic Auth header.

这篇关于将 HTTP 基本身份验证标头添加到 Backbone.js 同步函数可防止模型在 Save() 时更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆