Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS中用于管理受限页面的拦截器_Javascript_Angularjs_Angular Http_Angular Promise_Angular Http Interceptors - Fatal编程技术网

Javascript AngularJS中用于管理受限页面的拦截器

Javascript AngularJS中用于管理受限页面的拦截器,javascript,angularjs,angular-http,angular-promise,angular-http-interceptors,Javascript,Angularjs,Angular Http,Angular Promise,Angular Http Interceptors,几天前我刚开始使用AngularJS,我的拦截器从服务器响应中截取401个状态,我遇到了问题 当401被返回并且在该事件上触发重定向时,它广播类型为“loginRequired”的消息 问题是,如果我在未登录的情况下尝试访问受限页面,我会看到页面闪烁片刻,然后重定向到登录页面。我还是一个异步东西、承诺等方面的初学者。有人能指出我做错了什么吗 这是我的拦截器。正如你所看到的,它非常简单,但我精简了它来解释我的观点,我试图在进一步开发它之前理解它 拦截器 var services = angular

几天前我刚开始使用AngularJS,我的拦截器从服务器响应中截取401个状态,我遇到了问题

当401被返回并且在该事件上触发重定向时,它广播类型为“loginRequired”的消息

问题是,如果我在未登录的情况下尝试访问受限页面,我会看到页面闪烁片刻,然后重定向到登录页面。我还是一个异步东西、承诺等方面的初学者。有人能指出我做错了什么吗

这是我的拦截器。正如你所看到的,它非常简单,但我精简了它来解释我的观点,我试图在进一步开发它之前理解它

拦截器

var services = angular.module('services', []);

services.factory('myInterceptor', ['$q', '$rootScope',
  function($q,$rootScope) {

    var myInterceptor = {

      'responseError': function(rejection) {
        $rootScope.$broadcast('event:loginRequired');
        return $q.reject(rejection);
      }
    };

    return myInterceptor;
  }
]);
myApp.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
}]);
controllers.controller('RestrictedPageController', function($scope) {

  //Some times the alert pops up, sometimes not.
  alert("Damn it I shouldn't be there");

});
$rootScope.$on('event:loginRequired', function() {

  //Only redirect if we aren't on free access page
  if ($location.path() == "/freeAccess")
    return;

  //else go to the login page
  $location.path('/home').replace();

});
我的拦截器的注入

var services = angular.module('services', []);

services.factory('myInterceptor', ['$q', '$rootScope',
  function($q,$rootScope) {

    var myInterceptor = {

      'responseError': function(rejection) {
        $rootScope.$broadcast('event:loginRequired');
        return $q.reject(rejection);
      }
    };

    return myInterceptor;
  }
]);
myApp.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
}]);
controllers.controller('RestrictedPageController', function($scope) {

  //Some times the alert pops up, sometimes not.
  alert("Damn it I shouldn't be there");

});
$rootScope.$on('event:loginRequired', function() {

  //Only redirect if we aren't on free access page
  if ($location.path() == "/freeAccess")
    return;

  //else go to the login page
  $location.path('/home').replace();

});
受限页面的路由

.when('/restrictedPage', {
  templateUrl: 'partials/restrictedPage.html',
  controller: 'RestrictedPageController'
}).
受限页面控制器

var services = angular.module('services', []);

services.factory('myInterceptor', ['$q', '$rootScope',
  function($q,$rootScope) {

    var myInterceptor = {

      'responseError': function(rejection) {
        $rootScope.$broadcast('event:loginRequired');
        return $q.reject(rejection);
      }
    };

    return myInterceptor;
  }
]);
myApp.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
}]);
controllers.controller('RestrictedPageController', function($scope) {

  //Some times the alert pops up, sometimes not.
  alert("Damn it I shouldn't be there");

});
$rootScope.$on('event:loginRequired', function() {

  //Only redirect if we aren't on free access page
  if ($location.path() == "/freeAccess")
    return;

  //else go to the login page
  $location.path('/home').replace();

});
$rootScope事件观察程序

var services = angular.module('services', []);

services.factory('myInterceptor', ['$q', '$rootScope',
  function($q,$rootScope) {

    var myInterceptor = {

      'responseError': function(rejection) {
        $rootScope.$broadcast('event:loginRequired');
        return $q.reject(rejection);
      }
    };

    return myInterceptor;
  }
]);
myApp.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
}]);
controllers.controller('RestrictedPageController', function($scope) {

  //Some times the alert pops up, sometimes not.
  alert("Damn it I shouldn't be there");

});
$rootScope.$on('event:loginRequired', function() {

  //Only redirect if we aren't on free access page
  if ($location.path() == "/freeAccess")
    return;

  //else go to the login page
  $location.path('/home').replace();

});
我的问题显然是如何处理拦截器和$q。我找到了另一种在上创建拦截器的方法,但这不是官方文档使用的方法,因此我认为这可能是旧方法,而且在我看来,它不像放在工厂中那样干净。他只是在他的模块的config函数中定义了路由之后,才把这段代码放进去。但是这段代码有效,我没有看到页面闪烁

我在Github上找到的另一种方式

var interceptor = ['$rootScope', '$q', '$log',
  function(scope, $q, $log) {

    function success(response) {
      return response;
    }

    function error(response) {
      var status = response.status;

      if (status == 401) {
        var deferred = $q.defer();
        var req = {
          config: response.config,
          deferred: deferred
        };
        scope.$broadcast('event:loginRequired');
        return deferred.promise;
      }
      // otherwise
      return $q.reject(response);

    }

    return function(promise) {
      return promise.then(success, error);
    };

  }
];
$httpProvider.responseInterceptors.push(interceptor);

但我的目标不仅仅是“让它工作”,我讨厌“如果它没有坏,就不要修复它”的咒语。我想了解我的代码有什么问题。谢谢

请尝试在拦截器内执行位置路径更改,而不是从拦截器广播“event:loginRequired”。广播将增加接收401和更改位置之间的延迟,可能是屏幕“闪烁”的原因

services.factory('myInterceptor', ['$q', '$rootScope', '$location',
  function($q, $rootScope, $location) {

    var myInterceptor = {

      'responseError': function(rejection) {
         if (response.status === 401 && $location.path() !== '/freeAccess') {
           //else go to the login page
           $location.path('/home').replace();
         }
         // otherwise
         return $q.reject(response);
      }
    };

    return myInterceptor;
  }
]);
您还可以在应用程序模块首次运行时执行HTTP请求,以立即确定用户是否获得授权:

myApp.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
}])
.run(function($http) {
  //if this returns 401, your interceptor will be triggered
  $http.get('some-endpoint-to-determine-auth'); 
});

非常感谢!这很好用!哇,我真不敢相信我没有想到在我的拦截器中注入$location。