AngularJS withCredentials

Wou*_*ter 45 angularjs

我一直在研究AngularJS项目,该项目必须将AJAX调用发送到restfull webservice.这个web服务在另一个域上,所以我不得不在服务器上启用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");
Run Code Online (Sandbox Code Playgroud)

我能够将AngularJS的AJAX请求发送到后端但是当我尝试获取会话属性时我遇到了问题.我相信这是因为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);
        }
    })
});
Run Code Online (Sandbox Code Playgroud)

我面临的问题是我无法使用$ 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);
            });
Run Code Online (Sandbox Code Playgroud)

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

iwe*_*ein 68

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

$http.post(url, {withCredentials: true, ...})
Run Code Online (Sandbox Code Playgroud)

或旧版本:

$http({withCredentials: true, ...}).post(...)
Run Code Online (Sandbox Code Playgroud)

另见您的其他问题.

  • +1如果你使用的是ngresource,你会用`'getUserDetail'声明方法调用:{method:'GET',params:{},withCredentials:true} (8认同)
  • 在这种情况下,旧版本和新版本是? (2认同)

Pra*_*dra 52

在你的app配置功能中添加:

$httpProvider.defaults.withCredentials = true;
Run Code Online (Sandbox Code Playgroud)

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

别忘了注射 $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;
}
Run Code Online (Sandbox Code Playgroud)