Обработать перенаправления в angularjs $http
Im, использующий http-сервис angularjs в моем приложении. и я заметил это на веб-сайте
Если вызов AJAX завершается успешно (сервер отправляет обратно HTTP-код между 200 и 209), функция, переданная функции success(), казнены. Если вызов AJAX завершается неудачно (все остальные коды, кроме перенаправления), функция, переданная методу error(), выполняется.
очевидно, что код статуса перенаправления не является частью успеха, а не вызывает обратные вызовы.
Итак, как мы будем обрабатывать перенаправления?
Это то, что делает мой script, получает данные с сервера с помощью http get. Если сеанс истекает, сервер возвращает код состояния 302. Я должен поймать этот код состояния, а затем перенаправить страницу для входа.
app.controller('GraphController', function($scope, $http, localStorageService, $interval) {
$scope.GraphData = [{"key":"in","values":[]},{"key":"out","values":[]}];
$scope.pollStats = function() {
$http.get('/statistics/getStat').success(function(lastData, status, headers) {
if (status==302) {
//this doesn't work
//window.location=headers('Location');
//this doesn't work either
window.location.replace(headers('Location'));
}else if (status==200) {
...processData
}
});
};
});
Очевидно, что мой script не будет работать, потому что переадресация дескриптора запроса не работает. Итак, как мы должны справиться с этим?
Ответы
Ответ 1
Обратите внимание, что это относится к моему проекту.
Цель: вывести код статуса 302 и перенаправить страницу (для входа в мой пароль).
Результат. В firebug я мог видеть, что код ответа 302, но затем я обнаружил, что angularjs возвращает 200, просто распечатав значение status (response.status). Поэтому сначала вы подумали, что вы безнадежны. Но в моем случае я получил данные (response.data), ища строку, которая может быть найдена только на моей странице входа. Тогда это. проблема решена: D
Идея была взята здесь.
Здесь код
app.factory('redirectInterceptor', function($q,$location,$window){
return {
'response':function(response){
if (typeof response.data === 'string' && response.data.indexOf("My Login Page")>-1) {
console.log("LOGIN!!");
console.log(response.data);
$window.location.href = "/login.html";
return $q.reject(response);
}else{
return response;
}
}
}
});
app.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('redirectInterceptor');
}]);
Ответ 2
Я столкнулся с этой проблемой, пытаясь найти хороший способ реализации того, что пользователю будет предложено изменить свой пароль при первом входе в систему.
То, как я решил эту проблему, - это позволить серверу вернуть (неофициальный) код состояния 210 с заголовком местоположения, содержащим информацию, необходимую для поставщика состояния интерфейса UI-Router. В контроллере на передней панели я добавил:
if (data.status == 210) {
var location = data.headers().location;
$state.go(location);
} else {
$state.go("user", {name: data.data.fullName, userId: data.data.userId});
}
Ответ 3
Я думаю, что есть лучший способ, чем перехватчик http для переадресации входа, потому что он анализирует ответ запроса и если на другой странице запрашивается строка, произойдет ошибка.
Я предлагаю обернуть методы http в вашей службе и проверить, зарегистрирован ли пользователь перед тем, как сделать запрос:
app.service('httpWrapper', ['$http','requestLogin',function($http,requestLogin){
var httpWrapper = {};
// You can add methods for put, post
httpWrapper.get = function(url){
// Before making the request, check with a request if the user is logged
$http.get(urlLogged).success(function (auth) {
if(!auth.logged){
// Show login widget
requestLogin.show();
}
}).error(function(){
});
return $http.get(url);
}
return httpWrapper;
}]);
Затем использует httpWrapper вместо $http в ваших других сервисах:
app.service('otherService', ['httpWrapper',function(httpWrapper){
httpWrapper.get(url);
}]);
Здесь служба для requestLogin:
app.service('requestLogin', ['$rootScope',function($rootScope){
var requestLogin = {};
$rootScope.showlogin = false;
requestLogin.show = function(){
$rootScope.showlogin = true;
}
requestLogin.hide = function(){
$rootScope.showlogin = false;
}
return requestLogin;
}]);
И затем, на ваш взгляд:
<div ng-show="showlogin == true">
Please log-in...
</div>