【问题标题】:AngularJS withCredentialsAngularJS withCredentials
【发布时间】:2012-11-24 08:37:06
【问题描述】:

我一直在从事一个 AngularJS 项目,该项目必须将 AJAX 调用发送到一个 restfull 网络服务。这个网络服务在另一个域上,所以我必须在服务器上启用 cors。我通过设置这些标题来做到这一点:

cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "http://localhost:8000");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");

我能够将 AJAX 请求从 AngularJS 发送到后端,但是当我尝试获取会话的属性时遇到了问题。我相信这是因为 sessionid cookie 没有发送到后端。

我可以通过将 withCredentials 设置为 true 在 jQuery 中解决此问题。

$("#login").click(function() {
    $.ajax({
        url: "http://localhost:8080/api/login",
        data : '{"identifier" : "admin", "password" : "admin"}',
        contentType : 'application/json',
        type : 'POST',
        xhrFields: {
            withCredentials: true
        },
        success: function(data) {
            console.log(data);
        },
        error: function(data) {
            console.log(data);
        }
    })
});

$("#check").click(function() {
    $.ajax({
        url: "http://localhost:8080/api/ping",
        method: "GET",
        xhrFields: {
            withCredentials: true
        },
        success: function(data) {
            console.log(data);
        }
    })
});

我面临的问题是我无法通过 $http 服务在 AngularJS 中使用它。我试过这样:

$http.post("http://localhost:8080/api/login", $scope.credentials, {withCredentials : true}).
            success(function(data) {
                $location.path('/');
                console.log(data);
            }).
            error(function(data, error) {
                console.log(error);
            });

谁能告诉我我做错了什么?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    澄清:

    $http.post(url, {withCredentials: true, ...}) 
    

    应该是

    $http.post(url, data, {withCredentials: true, ...})
    

    根据https://docs.angularjs.org/api/ng/service/$http

    【讨论】:

      【解决方案2】:

      在您的应用配置函数中添加:

      $httpProvider.defaults.withCredentials = true;
      

      它将为您的所有请求附加此标头。

      别忘了注入$httpProvider

      编辑:2015-07-29

      这是另一个解决方案:

      HttpIntercepter 可用于添加常用的头部和常用的参数。

      在你的配置中添加这个:

      $httpProvider.interceptors.push('UtimfHttpIntercepter');

      并创建名称为UtimfHttpIntercepter的工厂

          angular.module('utimf.services', [])
          .factory('UtimfHttpIntercepter', UtimfHttpIntercepter)
      
          UtimfHttpIntercepter.$inject = ['$q'];
          function UtimfHttpIntercepter($q) {
          var authFactory = {};
      
          var _request = function (config) {
              config.headers = config.headers || {}; // change/add hearders
              config.data = config.data || {}; // change/add post data
              config.params = config.params || {}; //change/add querystring params            
      
              return config || $q.when(config);
          }
      
          var _requestError = function (rejection) {
              // handle if there is a request error
              return $q.reject(rejection);
          }
      
          var _response = function(response){
              // handle your response
              return response || $q.when(response);
          }
      
          var _responseError = function (rejection) {
              // handle if there is a request error
              return $q.reject(rejection);
          }
      
          authFactory.request = _request;
          authFactory.requestError = _requestError;
          authFactory.response = _response;
          authFactory.responseError = _responseError;
          return authFactory;
      }
      

      【讨论】:

        【解决方案3】:

        你应该传递一个配置对象,像这样

        $http.post(url, {withCredentials: true, ...})
        

        或在旧版本中:

        $http({withCredentials: true, ...}).post(...)
        

        另见your other question

        【讨论】:

        • +1 如果您使用的是 ngresource,您可以使用 'getUserDetail': { method:'GET', params: {}, withCredentials: true} 之类的方式声明方法调用
        • 在这种情况下,只有 withCredentials: true 以该形式或选项 Content-Type、Accept、crossDomain、Access-Control-Allow-Credentials/Origin/Headers?
        • 这种情况下新旧版本是?
        • @wanttobeprofessional 我没有检查,如果您找到确切的界限,请随时提出修改建议。这东西在 2014 年已经过时了……
        • 有谁知道,为什么会有如此大的不同?我比较了有和没有withCredentials 的所有请求和响应(OPTIONS 和 POST),没有发现任何区别。也许chrome的调试模式隐藏了一些细节?
        猜你喜欢
        • 2014-04-01
        • 1970-01-01
        • 2014-04-17
        • 2016-12-01
        • 1970-01-01
        • 2016-01-05
        • 2016-10-07
        • 2013-11-09
        • 2016-07-31
        相关资源
        最近更新 更多