在主干上添加请求标头

问题描述:

我的服务器有手动授权。我需要将我的服务器的用户名/密码放到我的骨干请求中,以便通过它。我该怎么做?有任何想法吗?谢谢在主干上添加请求标头

Backbone中的模型使用方法fetch,savedestroy检索,更新和销毁数据。这些方法将实际的请求部分委托给Backbone.sync。在引擎盖下,所有Backbone.sync正在做的是使用jQuery创建一个ajax请求。为了结合你的基本HTTP认证,你有两个选项。

fetch,savedestroy都接受附加参数[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)))); 
} 

并将其包含在每个fetchsavedestroy打电话给你做。像这样:

fetch({ 
    beforeSend: sendAuthentication 
}); 

这可以产生相当多的重复。另一个选项可以是覆盖Backbone.sync方法,复制原始代码并将beforeSend选项包含在每个jQuery ajax请求中。

希望这会有所帮助!

+0

试过你的代码。但没有回应。它不会调用该服务。 – jongbanaag 2012-04-10 03:21:57

+0

根本没有反应?或者你是否收到401回应码? – shanewwarren 2012-04-10 04:14:54

+1

nope。无论如何。你能给我一个关于如何重写backbone.sync到头文件的示例代码吗? – jongbanaag 2012-04-10 05:12:09

在Backbone.js中添加请求标头的最简单方法是将它们作为参数传递给获取方法。

MyCollection.fetch({ headers: {'Authorization' :'Basic USERNAME:PASSWORD'} }); 
+0

这对我来说很奇怪!如果有人想知道的话,那么当我输入文档时就不会出现在文档中。非常简单的方式来处理它)令人惊叹。 >谢谢! – albertpeiro 2013-06-20 12:28:53

+1

工作,除非用户名有一个:其中,你真的应该base64编码的用户名:密码 – dstarh 2013-08-16 20:43:46

Object.save(
    {'used': true} 
    {headers: {'Access-Token': 'access_token'}} 
) 
+0

这是全球? – Trip 2013-01-25 19:13:47

+0

这与上述['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应用程序,这可能不是最好的方法,请参见下面的评论。为了参考而留下答案。

+1

虽然它看起来可以工作,但**不要使用此** [我在另一个答案中描述的原因](https://stackoverflow.com/a/41991573/1218980)。 – 2017-12-22 06:19:05

+1

我倾向于同意,现在我的回答已经很老了。我要说的唯一的事情是,如果你正在用一个数据源进行一个简单的实验,这将是一个快速前进的方法。所以我可以把它留在这里作为参考。 – 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(); 

也许这是一种技巧,但它完全适用于我的系统。

+0

也许你可以解释一下这个问题是如何回答的? – 2015-06-05 02:01:18

+0

谢谢,这工作得很好。 – Cymen 2015-06-30 18:00:37

+0

这是一个黑客,不应该用于[我的另一个答案](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', 

}); 
+1

我喜欢你的解决方案!但是在返回行中,我会调用'Backbone.Model.prototype.sync.apply(this,arguments)'来代替。 – 2016-04-05 11:59:42

+0

@ cristian-conedera你是对的,那将是一种更加优雅和正确的方式。按照您的建议更改代码 – 2016-04-05 12:04:43

+1

我只是在新的beforeSend回调中添加对原始'beforeSend'选项(如果通过)的调用。请参阅注释源以供参考:http://backbonejs.org/docs/backbone.html#section-179 – 2016-07-06 17:07:10

  1. 在客户机端,任何服务器的通信之前添加此:

    $.ajaxSetup({ 
        xhrFields: { 
         withCredentials: true 
        }, 
        async: true 
    }); 
    
  2. 在服务器端添加这些报头(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 
    }); 
+0

这是一个好方法,但不是覆盖'sync'函数,而应该覆盖它并调用父类,不保证是'Backbone.sync'。 – 2017-12-22 06:28:10