我是AngularJS的新手,现在花了3天时间找到处理401状态的方法。我尝试过使用$ http的拦截器,使用$ resource ...但没有任何工作。我的应用程序在同一台服务器上调用JSONP调用。当发生错误时,它会被错误回调函数捕获。但状态始终为0且响应未定义。
首先,我尝试了这个拦截器
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.responseInterceptors.push(['$q', function($q) {
return function(promise) {
return promise.then(function(response) {
console.log('success in interceptor');
return response;
}, function(response) {
console.log('error in interceptor');
console.log(response);
if (response.status === 401) {
response.data = {
status: false,
description: 'Authentication required!'
};
return response;
}
return $q.reject(response);
});
}
}]);
}]);
其次,也在使用$ resource
的控制器中尝试过 $scope.fetchData = function(fromDate, toDate){
Cancel.get({from: fromDate, to: toDate, perPage: 99999},
function(data){
$scope.cancels = $scope.filteredCancels = data.data;
$scope.search();
},
function(response) {
$scope.errorMessage = '<h4>Error : '+response.status+'</h4>';
window.location = "/";
});
};
第三,尝试使用$ http而不是$ resource
$scope.fetchData = function(fromDate, toDate){
$http.jsonp('http://host:8900/api/cancellations?callback=JSON_CALLBACK')
.success(function(data, status, headers, config) {
console.log(status);
})
.error(function(data, status, headers, config) {
console.log(status);
};
以下是JSONP调用的标头信息
Request URL:http://host:8900/api/cancellations?callback=angular.callbacks._0
Request Method:GET
Status Code:401 Unauthorized
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Cache-Control:max-age=0
Connection:keep-alive
Cookie:__utma=149207145.339724205.1374885003.1377550245.1378313049.3; __utmc=149207145; __utmz=149207145.1378313049.3.2.utmcsr=cyphersmart.qc3deva.electricmail.com:8900|utmccn=(referral)|utmcmd=referral|utmcct=/; remember_username=elie.kim%40electricmail.com; PHPSESSID=gdoemlp5jltqq62etc5gfuh653; cookie=cookiecheck; __utma=1.789184132.1378340585.1378499390.1378504453.10; __utmb=1.3.10.1378504453; __utmc=1; __utmz=1.1378340585.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Host:host:8900
Referer:http://host:8900/reports/cancels/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22
Query String Parametersview sourceview URL encoded
callback:angular.callbacks._0
Response Headersview source
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Type:application/json; charset=utf-8
Date:Fri, 06 Sep 2013 22:02:13 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=20
Pragma:no-cache
Server:nginx/0.7.65
Transfer-Encoding:chunked
我找不到办法处理未经授权的状态401,但我把所有东西捆绑在一起。如果我能得到小费或善意的建议,我将不胜感激。
答案 0 :(得分:7)
接受的答案不适用于更高版本的角度。使用1.5.x(甚至更早)你需要以不同的方式编写拦截器:
// http interceptor to handle redirection to login on 401 response from API
app.factory('httpResponseInterceptor', ['$q', '$rootScope', '$location', function($q, $rootScope, $location) {
return {
responseError: function(rejection) {
if (rejection.status === 401) {
// Something like below:
$location.path('signin/invalidSession');
}
return $q.reject(rejection);
}
};
}]);
申请:
app.config(function($httpProvider) {
$httpProvider.interceptors.push('httpResponseInterceptor');
});
详情请见https://docs.angularjs.org/api/ng/service/ $ http#interceptors
答案 1 :(得分:4)
我最近需要做的非常相似,这是我的拦截器
app.factory("HttpErrorInterceptorModule", ["$q", "$rootScope", "$location",
function($q, $rootScope, $location) {
var success = function(response) {
// pass through
return response;
},
error = function(response) {
if(response.status === 401) {
// dostuff
}
return $q.reject(response);
};
return function(httpPromise) {
return httpPromise.then(success, error);
};
}
]).config(["$httpProvider",
function($httpProvider) {
$httpProvider.responseInterceptors.push("HttpErrorInterceptorModule");
}
]);
为您的用例修改了轻微
答案 2 :(得分:3)
如果任何API调用返回401,我们必须将用户重定向到登录页面。 Angular的HTTP拦截器非常适合这项工作。正如您从上面的app.js中看到的那样,它已被推到管道:
httpProvider.responseInterceptors.push('httpInterceptor');
拦截器实现本身,
'use strict';
angular.module('dashboardApp').factory('httpInterceptor', function httpInterceptor ($q, $window, $location) {
return function (promise) {
var success = function (response) {
return response;
};
var error = function (response) {
if (response.status === 401) {
$location.url('/login');
}
return $q.reject(response);
};
return promise.then(success, error);
};
});
答案 3 :(得分:2)
遵循类似的解决方案......
angular.module('myApp', ['myApp.services', 'myApp.directives'], function ($routeProvider, $locationProvider, $httpProvider, $location) {
var httpInterceptor = ['$rootScope', '$q', function (scope, $q) {
function success(response) {
return response;
}
function error(response) {
var status = response.status;
if (status == 401) {
$location.url('/login');
return;
}
return $q.reject(response);
}
return function (promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(httpInterceptor);
});