【问题标题】:Angular.js $http.post TypeError: Cannot read property 'data' of undefinedAngular.js $http.post TypeError:无法读取未定义的属性“数据”
【发布时间】:2013-05-11 11:35:43
【问题描述】:

Angular.js v1.0.6

当发出 $http.post 并收到非 200 响应(在本例中为 401)时

$http.post('http://localhost:3030/auth/login', {
  username: 'username',
  password: 'password'
})
.success(function(data) {
  // Gets called on a 200 response, but not on a 401
  console.log('success');
})
.error(function(err) {
  // Never gets called & dies with error described below.
  console.log('error');
});

Angular 抛出以下错误:

TypeError: Cannot read property 'data' of undefined
    at http://localhost:9000/components/angular/angular.js:8891:22
    at wrappedCallback (http://localhost:9000/components/angular/angular.js:6797:59)
    at http://localhost:9000/components/angular/angular.js:6834:26
    at Object.Scope.$eval (http://localhost:9000/components/angular/angular.js:8011:28)
    at Object.Scope.$digest (http://localhost:9000/components/angular/angular.js:7876:25)
    at Object.Scope.$apply (http://localhost:9000/components/angular/angular.js:8097:24)
    at done (http://localhost:9000/components/angular/angular.js:9111:20)
    at completeRequest (http://localhost:9000/components/angular/angular.js:9274:7)
    at XMLHttpRequest.xhr.onreadystatechange (http://localhost:9000/components/angular/angular.js:9244:11) 

并且永远不要调用.success() 回调或.error() errback,从而无法处理响应。

我做错了吗?成功回调会在提供合法凭据时按预期调用。

200 响应:

Access-Control-Allow-Headers:Content-Type, Authorization, Content-Length, X-Requested-With, Auth-Token
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:99
Content-Type:application/json
Date:Thu, 16 May 2013 13:57:51 GMT

{
  "auth-token":"676932cc1e183a64334345944ad432d1908f8110bc",
  "user": {
    "id":1,
    "username":"username"
  }
}

401 响应:

Access-Control-Allow-Headers:Content-Type, Authorization, Content-Length, X-Requested-With, Auth-Token
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:45
Content-Type:application/json
Date:Thu, 16 May 2013 13:58:25 GMT

{
  "error": [
    {
      "message":"Invalid Credentials"
    }
  ]
}

此外,如果我采用正常的 promise 语法来支持 .success() 快捷方式,我会得到一些有趣的行为:

$http.post('http://localhost:3030/auth/login', {
  username: username,
  password: password
}).then(function (resp) {
  // On a 200 response, resp is a response object.
  // On a 401 response, resp is undefined.
  console.log(resp);
}, function() {
  console.log('error');
});

【问题讨论】:

    标签: javascript http authentication angularjs http-status-code-401


    【解决方案1】:

    终于明白了。问题是由以下全局 HTTP 拦截器实现引起的:

    'use strict';
    // register the interceptor as a service
    angular.module('imvgm')
      .factory('httpInterceptor', ['$q', '$rootScope',  function($q, $rootScope) {
    
      function success(response) {
        return response;
      }
    
      function error(response) {
        var status = response.status;
    
        if (status === 401) {
          $rootScope.$broadcast('event:loginRequired');
          return
        }
        // otherwise
        return $q.reject(response);
      }
    
      return function(promise) {
        return promise.then(success, error);
      };
    
    }]);
    

    注意

    if (status === 401) {
      $rootScope.$broadcast('event:loginRequired');
      return // Returns nothing
    }
    

    修复:

    if (status === 401) {
      $rootScope.$broadcast('event:loginRequired');
    }
    

    【讨论】:

    • 我遇到了类似的问题,但在我的示例中,我不想将执行传播到本地承诺,这就是为什么我没有返回 $q.reject(response) 而只是返回一个空对象 {};
    • 谢谢。我也有这个问题很久了。最后我也修好了。
    猜你喜欢
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    相关资源
    最近更新 更多