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使得无法处理响应。
.success()
.error()
难道我做错了什么?成功回叫将在提供合法凭据时按预期方式被调用。
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'); });
终于深入到此。该问题是由于以下全局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); }; }]);
NB
if (status === 401) { $rootScope.$broadcast('event:loginRequired'); return // Returns nothing }
固定:
if (status === 401) { $rootScope.$broadcast('event:loginRequired'); }