Lo sto facendo usando intercettori. Ho creato un file di libreria che può essere aggiunto al file index.html. In questo modo avrai una gestione globale degli errori per le chiamate di servizio di riposo e non dovrai preoccuparti di tutti gli errori singolarmente. Più in basso ho anche incollato la mia libreria di login di base-auth. Lì puoi vedere che controllo anche l'errore 401 e reindirizzo a una posizione diversa. Vedi lib / ea-basic-auth-login.js
lib / http-error-handling.js
/**
* @ngdoc overview
* @name http-error-handling
* @description
*
* Module that provides http error handling for apps.
*
* Usage:
* Hook the file in to your index.html: <script src="lib/http-error-handling.js"></script>
* Add <div class="messagesList" app-messages></div> to the index.html at the position you want to
* display the error messages.
*/
(function() {
'use strict';
angular.module('http-error-handling', [])
.config(function($provide, $httpProvider, $compileProvider) {
var elementsList = $();
var showMessage = function(content, cl, time) {
$('<div/>')
.addClass(cl)
.hide()
.fadeIn('fast')
.delay(time)
.fadeOut('fast', function() { $(this).remove(); })
.appendTo(elementsList)
.text(content);
};
$httpProvider.responseInterceptors.push(function($timeout, $q) {
return function(promise) {
return promise.then(function(successResponse) {
if (successResponse.config.method.toUpperCase() != 'GET')
showMessage('Success', 'http-success-message', 5000);
return successResponse;
}, function(errorResponse) {
switch (errorResponse.status) {
case 400:
showMessage(errorResponse.data.message, 'http-error-message', 6000);
}
}
break;
case 401:
showMessage('Wrong email or password', 'http-error-message', 6000);
break;
case 403:
showMessage('You don\'t have the right to do this', 'http-error-message', 6000);
break;
case 500:
showMessage('Server internal error: ' + errorResponse.data.message, 'http-error-message', 6000);
break;
default:
showMessage('Error ' + errorResponse.status + ': ' + errorResponse.data.message, 'http-error-message', 6000);
}
return $q.reject(errorResponse);
});
};
});
$compileProvider.directive('httpErrorMessages', function() {
return {
link: function(scope, element, attrs) {
elementsList.push($(element));
}
};
});
});
})();
css / http-error-handling.css
.http-error-message {
background-color: #fbbcb1;
border: 1px #e92d0c solid;
font-size: 12px;
font-family: arial;
padding: 10px;
width: 702px;
margin-bottom: 1px;
}
.http-error-validation-message {
background-color: #fbbcb1;
border: 1px #e92d0c solid;
font-size: 12px;
font-family: arial;
padding: 10px;
width: 702px;
margin-bottom: 1px;
}
http-success-message {
background-color: #adfa9e;
border: 1px #25ae09 solid;
font-size: 12px;
font-family: arial;
padding: 10px;
width: 702px;
margin-bottom: 1px;
}
index.html
<!doctype html>
<html lang="en" ng-app="cc">
<head>
<meta charset="utf-8">
<title>yourapp</title>
<link rel="stylesheet" href="css/http-error-handling.css"/>
</head>
<body>
<!-- Display top tab menu -->
<ul class="menu">
<li><a href="#/user">Users</a></li>
<li><a href="#/vendor">Vendors</a></li>
<li><logout-link/></li>
</ul>
<!-- Display errors -->
<div class="http-error-messages" http-error-messages></div>
<!-- Display partial pages -->
<div ng-view></div>
<!-- Include all the js files. In production use min.js should be used -->
<script src="lib/angular114/angular.js"></script>
<script src="lib/angular114/angular-resource.js"></script>
<script src="lib/http-error-handling.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
lib / EA-base-auth-login.js
Quasi lo stesso può essere fatto per il login. Qui hai la risposta al reindirizzamento ($ location.path ("/ login")).
/**
* @ngdoc overview
* @name ea-basic-auth-login
* @description
*
* Module that provides http basic authentication for apps.
*
* Usage:
* Hook the file in to your index.html: <script src="lib/ea-basic-auth-login.js"> </script>
* Place <ea-login-form/> tag in to your html login page
* Place <ea-logout-link/> tag in to your html page where the user has to click to logout
*/
(function() {
'use strict';
angular.module('ea-basic-auth-login', ['ea-base64-login'])
.config(['$httpProvider', function ($httpProvider) {
var ea_basic_auth_login_interceptor = ['$location', '$q', function($location, $q) {
function success(response) {
return response;
}
function error(response) {
if(response.status === 401) {
$location.path('/login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(ea_basic_auth_login_interceptor);
}])
.controller('EALoginCtrl', ['$scope','$http','$location','EABase64Login', function($scope, $http, $location, EABase64Login) {
$scope.login = function() {
$http.defaults.headers.common['Authorization'] = 'Basic ' + EABase64Login.encode($scope.email + ':' + $scope.password);
$location.path("/user");
};
$scope.logout = function() {
$http.defaults.headers.common['Authorization'] = undefined;
$location.path("/login");
};
}])
.directive('eaLoginForm', [function() {
return {
restrict: 'E',
template: '<div id="ea_login_container" ng-controller="EALoginCtrl">' +
'<form id="ea_login_form" name="ea_login_form" novalidate>' +
'<input id="ea_login_email_field" class="ea_login_field" type="text" name="email" ng-model="email" placeholder="E-Mail"/>' +
'<br/>' +
'<input id="ea_login_password_field" class="ea_login_field" type="password" name="password" ng-model="password" placeholder="Password"/>' +
'<br/>' +
'<button class="ea_login_button" ng-click="login()">Login</button>' +
'</form>' +
'</div>',
replace: true
};
}])
.directive('eaLogoutLink', [function() {
return {
restrict: 'E',
template: '<a id="ea-logout-link" ng-controller="EALoginCtrl" ng-click="logout()">Logout</a>',
replace: true
}
}]);
angular.module('ea-base64-login', []).
factory('EABase64Login', function() {
var keyStr = 'ABCDEFGHIJKLMNOP' +
'QRSTUVWXYZabcdef' +
'ghijklmnopqrstuv' +
'wxyz0123456789+/' +
'=';
return {
encode: function (input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
keyStr.charAt(enc1) +
keyStr.charAt(enc2) +
keyStr.charAt(enc3) +
keyStr.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
},
decode: function (input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
alert("There were invalid base64 characters in the input text.\n" +
"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
"Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}
};
});
})();