处理angularjs $ http中的重定向

时间:2015-04-06 10:14:48

标签: angularjs redirect

我在我的应用程序中使用angularjs http服务。我在website

中注意到了这一点
  

如果AJAX调用成功(服务器在之间发送回HTTP代码)   200和209),传递给success()函数的函数是   执行。如果AJAX调用失败(除了。之外的所有其他代码)   重定向),执行传递给error()方法的函数。

显然,重定向状态代码不是成功的一部分,也不是错误回调。 那么我们如何处理重定向?

这是我的脚本所做的,使用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
                }
            });
        };
});

显然我的脚本不会工作,因为成功回调无法处理重定向。那我们该如何应对呢?

3 个答案:

答案 0 :(得分:31)

请注意,这是我的项目特有的。

目标:抓住302状态代码并重定向页面(在我的情况下登录)。

结果:在firebug中,我可以看到响应代码是302,但后来我发现angularjs只需打印status(response.status)值就会返回200。所以一开始你认为自己没有希望。但在我的情况下,我所做的是获取数据(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');
    }]); 

答案 1 :(得分:1)

我也遇到了这个问题,尝试找到一种很好的方法来实现在第一次登录时提示用户更改密码。

我解决此问题的方法是让服务器返回带有位置标头的(非官方)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});
}

答案 2 :(得分:0)

我认为有一种比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>