$ http响应Set-Cookie无法访问

Luk*_*uke 24 javascript cookies http http-headers angularjs

我正在为我的后端写一个angularjs前端,我遇到了一个常见的问题:

服务器在响应中发回cookie,但angular.js完全忽略了cookie(甚至无法打印出'Set-Cookie'值).

我试过读书

AngularJS会忽略HTTP标头中的Set-Cookie

Angularjs $ http似乎不理解响应中的"Set-Cookie"

但不幸的是,我已经尝试了所有的解决方案,但似乎没有用.

请求已发送

(由Chrome开发者工具捕获)

收到回复

(由Chrome开发者工具捕获)

我正在使用angular.js(v1.2.10),这就是我用来发出请求的内容

$http.post('/services/api/emailLogin',
           sanitizeCredentials(credentials), 
           {
              withCredentials: true
           }).success(function(data, status, header) {
                console.log(header('Server'));
                console.log(header('Set-Cookie'));
                console.log(header('Access-Control-Allow-Headers'));
                console.log(header('Access-Control-Allow-Methods'));
                console.log(header);
            }).then(
                function(response) {
                    console.log(response);
                    return response.data;
                });
Run Code Online (Sandbox Code Playgroud)

withCredentials=true 在发出请求之前在客户端设置.

Access-Control-Allow-Credentials=true 在返回响应之前在服务器端设置.

您可以清楚地看到Set-CookieChrome开发者工具的响应标题中,但打印输出正好

(代码打印输出)

Set-Cookie在响应头中没有打印出来.我想知道为什么会这样?有没有办法让我确定withCredentials=true确实设置(我没有在请求标题中看到它)?

任何帮助表示赞赏!

Ila*_*mer 29

我查看了$httpBackend源代码:

xhr.onreadystatechange = function() {

  // some code

  if (xhr && xhr.readyState == 4) {
    var responseHeaders = null,
        response = null;

    if(status !== ABORTED) {
      responseHeaders = xhr.getAllResponseHeaders();

      // some code
Run Code Online (Sandbox Code Playgroud)

它用于XMLHttpRequest#getAllResponseHeaders获取响应头.

经过一番搜索,我发现了这个问题:xmlHttp.getResponseHeader +不适用于CORS

这让我意识到XHR的规格并不支持SET-COOKIE,因此它与angular.js无关.

http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders%28%29-method

4.7.4 getAllResponseHeaders()方法

返回响应中的所有标头,但字段名称为Set-Cookie或Set-Cookie2的标头除外.


而只是使用$cookies:

它是一个不同的模块,因此您必须将其添加到脚本中

 <script src="angular.js"></script>
 <script src="angular-cookies.js"></script>
Run Code Online (Sandbox Code Playgroud)

并将其添加到模块依赖项:

 var app = angular.module('app',['ngCookies']);
Run Code Online (Sandbox Code Playgroud)

然后就像这样使用它:

app.controller('ctrl',  function($scope, $http , $cookies, $timeout){

  $scope.request = function(){

    $http.get('/api').then(function(response){
      $timeout(function(){
        console.log($cookies.session)
      });         
    })
  }
})
Run Code Online (Sandbox Code Playgroud)

我使用的$timeout是因为$cookies只有在摘要后才与浏览器的cookie同步.

  • @Ilan Frumer,这个解决方案在1.3.14版本的Angular中被打破了.任何的想法 ? (2认同)