在主干上添加请求标头
Backbone中的模型使用方法fetch
,save
和destroy
检索,更新和销毁数据。这些方法将实际的请求部分委托给Backbone.sync。在引擎盖下,所有Backbone.sync
正在做的是使用jQuery创建一个ajax请求。为了结合你的基本HTTP认证,你有两个选项。
fetch
,save
和destroy
都接受附加参数[options]
。这些[options]
只是一个jQuery请求选项的字典,它包含在jQuery ajax调用中。这意味着你可以很容易地定义其追加认证的简单方法:
sendAuthentication = function (xhr) {
var user = "myusername";// your actual username
var pass = "mypassword";// your actual password
var token = user.concat(":", pass);
xhr.setRequestHeader('Authorization', ("Basic ".concat(btoa(token))));
}
并将其包含在每个fetch
,save
和destroy
打电话给你做。像这样:
fetch({
beforeSend: sendAuthentication
});
这可以产生相当多的重复。另一个选项可以是覆盖Backbone.sync
方法,复制原始代码并将beforeSend
选项包含在每个jQuery ajax请求中。
希望这会有所帮助!
在Backbone.js中添加请求标头的最简单方法是将它们作为参数传递给获取方法。
MyCollection.fetch({ headers: {'Authorization' :'Basic USERNAME:PASSWORD'} });
这对我来说很奇怪!如果有人想知道的话,那么当我输入文档时就不会出现在文档中。非常简单的方式来处理它)令人惊叹。 >谢谢! – albertpeiro 2013-06-20 12:28:53
工作,除非用户名有一个:其中,你真的应该base64编码的用户名:密码 – dstarh 2013-08-16 20:43:46
Object.save(
{'used': true}
{headers: {'Access-Token': 'access_token'}}
)
这是全球? – Trip 2013-01-25 19:13:47
这与上述['fetch'示例](https://stackoverflow.com/a/11846129/1218980)的答案相同,但没有任何解释。 – 2017-12-22 06:29:31
您可以覆盖骨干同步方法。
#coffeescript
_sync = Backbone.sync
Backbone.sync = (method, model, options) ->
options.beforeSend = (xhr) ->
xhr.setRequestHeader('X-Auth-Token_or_other_header' , your_hash_key)
#make sure your server accepts X-Auth-Token_or_other_header!!
#calling the original sync function so we only overriding what we need
_sync.call(this, method, model, options)
一个选项可能是使用jQuery ajaxSetup,所有的Backbone请求最终都会使用底层的jQuery ajax。这种方法的好处是你只需要添加一个地方。
$.ajaxSetup({
headers: { 'Authorization' :'Basic USERNAME:PASSWORD' }
});
编辑2018年1月2日 对于复杂的Web应用程序,这可能不是最好的方法,请参见下面的评论。为了参考而留下答案。
虽然它看起来可以工作,但**不要使用此** [我在另一个答案中描述的原因](https://stackoverflow.com/a/41991573/1218980)。 – 2017-12-22 06:19:05
我倾向于同意,现在我的回答已经很老了。我要说的唯一的事情是,如果你正在用一个数据源进行一个简单的实验,这将是一个快速前进的方法。所以我可以把它留在这里作为参考。 – 2018-01-02 13:07:00
Backbone.$.ajaxSetup({
headers: {'Authorization' :'Basic USERNAME:PASSWORD'}
});
此代码将标题设置为Backbone ajax,因此它们将与每个Backbone.sync一起发送。每次同步呼叫时,您将能够发送标题,而不使用xhr.setRequestHeader
。
所以你不需要做每次执行以下操作:
MyCollection.fetch({ headers: {'Authorization' :'Basic USERNAME:PASSWORD'} });
你可以做
MyCollection.fetch();
也许这是一种技巧,但它完全适用于我的系统。
也许你可以解释一下这个问题是如何回答的? – 2015-06-05 02:01:18
谢谢,这工作得很好。 – Cymen 2015-06-30 18:00:37
这是一个黑客,不应该用于[我的另一个答案](https://stackoverflow.com/a/41991573/1218980)中解释的原因。这与[上面的$ .ajaxSetup']的答案相同(https://stackoverflow.com/a/20633326/1218980)。 – 2017-12-22 06:24:24
我的做法就是覆盖同步方法,以便在请求之前添加标头。 在该示例中,您可以看到我创建了一个Backbone.AuthenticatedModel
,该范围从Backbone.Model
延伸。
这将影响所有的方法(GET,POST,删除等)
Backbone.AuthenticatedModel = Backbone.Model.extend({
sync: function(method, collection, options){
options = options || {};
options.beforeSend = function (xhr) {
var user = "myusername";// your actual username
var pass = "mypassword";// your actual password
var token = user.concat(":", pass);
xhr.setRequestHeader('Authorization', ("Basic ".concat(btoa(token))));
};
return Backbone.Model.prototype.sync.apply(this, arguments);
}
});
然后,你必须简单扩展,你需要有认证的模式,从Backbone.AuthenticatedModel
已创建:
var Process = Backbone.AuthenticatedModel.extend({
url: '/api/process',
});
我喜欢你的解决方案!但是在返回行中,我会调用'Backbone.Model.prototype.sync.apply(this,arguments)'来代替。 – 2016-04-05 11:59:42
@ cristian-conedera你是对的,那将是一种更加优雅和正确的方式。按照您的建议更改代码 – 2016-04-05 12:04:43
我只是在新的beforeSend回调中添加对原始'beforeSend'选项(如果通过)的调用。请参阅注释源以供参考:http://backbonejs.org/docs/backbone.html#section-179 – 2016-07-06 17:07:10
-
在客户机端,任何服务器的通信之前添加此:
$.ajaxSetup({ xhrFields: { withCredentials: true }, async: true });
-
在服务器端添加这些报头(PHP):
header('Access-Control-Allow-Origin: http://your-client-app-domain'); header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With"); header('Access-Control-Allow-Credentials: true');
创建拦截来电Backbone.sync,配件您授权的报头,并通过通过一切自定义同步方法:
REPORTING_API_KEY = 'secretKeyHere';
CustomSync = function(method, model, options) {
options.headers = {
'Authorization' : 'Bearer ' + REPORTING_API_KEY
};
return Backbone.sync(method, model, options);
};
然后用一个覆盖模型的同步:
MyModel = Backbone.Model.extend({
urlRoot: '/api/',
sync: CustomSync
});
这是一个好方法,但不是覆盖'sync'函数,而应该覆盖它并调用父类,不保证是'Backbone.sync'。 – 2017-12-22 06:28:10
试过你的代码。但没有回应。它不会调用该服务。 – jongbanaag 2012-04-10 03:21:57
根本没有反应?或者你是否收到401回应码? – shanewwarren 2012-04-10 04:14:54
nope。无论如何。你能给我一个关于如何重写backbone.sync到头文件的示例代码吗? – jongbanaag 2012-04-10 05:12:09