【问题标题】:add request header on backbone在主干上添加请求标头
【发布时间】:2012-04-22 07:53:41
【问题描述】:

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

【问题讨论】:

    标签: jquery backbone.js


    【解决方案1】:

    尝试使用它。我们可以使用任一

    beforeSend: function(xhr) {
        xhr.setRequestHeader('X-CSRFToken', csrf_token);
    },
    

    或

    headers: {
        "X-CSRFToken": csrf_token
    },
    

    但我会推荐第一个选项(beforeSend)。

    这是我的工作代码 sn-p。

    var csrf_token = this.getCSRFToken();
    self.collection.fetch(
    {
        beforeSend: function(xhr) {
            xhr.setRequestHeader('X-CSRFToken', csrf_token);
        },
        // headers: {
        //     "X-CSRFToken": csrf_token
        // },
        data: {
            "mark_as": "read"
        },
        type: 'POST',
        success: function () {
            if (clickLink) {
                window.location.href = clickLink;
            } else {
                self.unreadNotificationsClicked(e);
                // fetch the latest notification count
                self.counter_icon_view.refresh();
            }
        },
        error: function(){
            alert('erorr');
        }
    });
    

    【讨论】:

      【解决方案2】:

      一种选择可能是使用 jQuery ajaxSetup,所有 Backbone 请求最终都将使用底层的 jQuery ajax。这种方法的好处是您只需将其添加到一个位置。

      $.ajaxSetup({
          headers: { 'Authorization' :'Basic USERNAME:PASSWORD' }
      });
      

      2018 年 1 月 2 日编辑 对于复杂的 Web 应用程序,这可能不是最好的方法,请参阅下面的 cmets。在这里留下答案以供参考。

      【讨论】:

      • 虽然它看起来可以工作,但对于the reasons I described in another answer,不要使用它。
      • 我倾向于同意,我的答案现在已经很老了。我唯一想说的是,如果您正在使用一个数据源进行简单的实验,这将是一种快速的开始方式。所以我可能会把它留在这里以供参考。
      【解决方案3】:
      Backbone.$.ajaxSetup({
          headers: {'Authorization' :'Basic USERNAME:PASSWORD'}
      });
      

      此代码将标头设置为 Backbone ajax,因此它们将与每个 Backbone.sync 一起发送。您无需在每次同步调用中使用xhr.setRequestHeader 即可发送标头。

      因此您无需每次都执行以下操作:

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

      你可以这样做

      MyCollection.fetch();
      

      也许这是一种 hack,但它非常适合我的系统。

      【讨论】:

      • 也许您可以解释一下这是如何回答问题的?
      • 由于another answer of mine 中解释的原因,这是一个不应使用的hack。也是和the $.ajaxSetup one above一样的答案。
      • 有没有办法定义响应拦截器? ajaxError 之类的?
      【解决方案4】:

      创建一个自定义同步方法,拦截对 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的父函数。
      【解决方案5】:
      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');
        

      【讨论】:

        【解决方案6】:

        我的处理方法是覆盖同步方法,以便在执行请求之前添加标头。 在示例中,您可以看到我正在创建一个 Backbone.AuthenticatedModel,它从 Backbone.Model 扩展而来。

        这将影响所有方法(GET、POST、DELETE 等)

        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)。
        • @cristian-conedera 你是对的,这将是一种更优雅和正确的方式。按照您的建议更改了代码
        • 我只需在新的 beforeSend 回调中添加对原始 beforeSend 选项(如果通过)的调用。参考注释来源:backbonejs.org/docs/backbone.html#section-179
        【解决方案7】:

        Backbone 中的模型使用fetch、save 和destroy 方法检索、更新和销毁数据。这些方法将实际请求部分委托给 Backbone.sync。在后台,Backbone.sync 所做的只是使用 jQuery 创建一个 ajax 请求。为了合并您的基本 HTTP 身份验证,您有几个选项。

        fetch、save 和 destroy 都接受附加参数 [options]。这些[options] 只是一个包含在jQuery ajax 调用中的jQuery 请求选项字典。这意味着您可以轻松定义一个附加身份验证的简单方法:

        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 请求中。

        希望这会有所帮助!

        【讨论】:

        • 试过你的代码。但没有回应。它不调用服务。
        • 完全没有反应?还是您收到 401 响应代码?
        • 不。无论如何。你能给我一个关于如何将主干同步覆盖到标题的示例代码吗?
        • 您能否提供一个您为此实现编写的backbone.js 代码示例?我在让它工作时遇到问题。你可以在this question看到我的进度
        • 我不会复制原始的 Backbone.sync 方法。您可以执行japhr.blogspot.com/2011/10/… 中建议的操作,但基本上只需覆盖options,然后调用Backbone.Model.prototype.fetch.call(this, options)。
        【解决方案8】:

        您可以覆盖 Backbone 同步方法。

        #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 )       
        

        【讨论】:

          【解决方案9】:

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

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

          【讨论】:

          • 这对我有用,令人惊讶!如果有人想知道,当我打字时它不在文档中。处理它的极其简单的方法;)太棒了。 >谢谢!
          • 除非用户名中有一个 : ,否则你真的应该base64编码用户名:密码
          【解决方案10】:
          Object.save(
            {'used': true}
            {headers: {'Access-Token': 'access_token'}}
          )
          

          【讨论】:

          猜你喜欢
          • 2016-08-22
          • 1970-01-01
          • 2016-12-22
          • 1970-01-01
          • 1970-01-01
          • 2015-03-22
          • 2011-05-04
          • 2021-07-03
          • 2015-08-30
          相关资源
          最近更新 更多