问题
I'm very newbie in AngularJS, and now spending 3 days in finding a way to handle 401 status. I've tried interceptors, using $http, using $resource...but nothing is working. My app calls JSONP call on the same server. when error occurs it is caught in error callback function. but the status is always 0 and the response is undefined.
First, I tried this interceptor
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);
});
}
}]);
}]);
Second, also tried in controllers using $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 = "/";
});
};
Third, tried using $http instead of $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);
};
Here is header information for the JSONP call
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
I couldn't find a way to handle the unauthorized status 401, I tied all the things though. It would be very appreciated if I can get a tip or kind advice.
回答1:
The accepted answer doesn't work for later versions of angular. Using 1.5.x (and maybe even earlier) you need to write the interceptor differently:
// 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);
}
};
}]);
Apply with:
app.config(function($httpProvider) {
$httpProvider.interceptors.push('httpResponseInterceptor');
});
See here for further information https://docs.angularjs.org/api/ng/service/$http#interceptors
回答2:
i needed to do very similar recently, here is my interceptor
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");
}
]);
modified slight for your use case
回答3:
In case of any API call returns 401 we have to redirect user to login page. Angular’s HTTP interceptor is great for that job. As you can see from app.js above, it’s been pushed to pipe here:
httpProvider.responseInterceptors.push('httpInterceptor');
The interceptor implementation itself,
'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);
};
});
回答4:
Follows a similar solution ...
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);
});
来源:https://stackoverflow.com/questions/18667740/401-unauthorized-error-handling-in-angularjs