【问题标题】:Get previous URL on Angular request interceptor在 Angular 请求拦截器上获取以前的 URL
【发布时间】:2015-10-19 23:39:45
【问题描述】:

我正在实现一个有角度的页面范围authentication app

它是一个使用拦截器的事件机器,所以如果任何请求导致 401 响应,它就会弹出一个登录模式。当登录成功时,它会再次执行请求(如果登录的用户没有足够的权限访问所请求的资源,这也可能导致 403)。

到目前为止,一切都按预期工作,只是当用户取消登录过程时,$location.path() 仍然指向请求的资源。我想将此恢复到以前的路径。所以:

我的预期

我希望能够像这样获得“被调用者”URL:

.factory('authInterceptor', ...
  return {
    // Append the authentication headers to every request
    request: function(config) {
      previousLocation = $location.path(); // <--- HERE
      if(Session.exist) {
        config.headers.Authorization = Session.token;
      }
      return config || $q.when(config);
    },

我希望这一行能给我“被调用者”路径,但它实际上给了我请求的路径(角度在执行请求之前已经改变了它)。

路由提供者

.config(['$routeProvider', function($routeProvider) {
  $routeProvider
  .when('/admin', {
    templateUrl: "/admin"
  })
  .otherwise({ redirectTo: '/' });
}])

这个顽皮的小男孩在请求之前改变了我的道路。我想我可以在这里解决一些问题,但我觉得这没什么用,因为它会完全破坏封装,迫使我每次调用任何受保护的资源时都要解决,所以我可以将当​​前路径传递给我的某些服务身份验证应用程序。

那么,如何在不从路由提供者配置中显式发送的情况下,从拦截器或身份验证应用程序中的某些服务中获取先前的路径?

【问题讨论】:

    标签: angularjs interceptor ngroute


    【解决方案1】:

    您为什么不观看$on 路由更改事件并将您当前/以前的路径绑定到$window 或全局$scope 变量?

    我还没有阅读您上面的所有代码,但这是我在应用程序中处理位置 事物 的方式:

    $scope.$on('$routeChangeSuccess', function(evt, current, previous){
        var routeData = {};
    
        //prop: uriSegment
        //desc: get all uri segments for current location
        routeData.uriSegment = [];
        routeData.uriSegment = $location.path().substr(1).split('/');
    
        //prop: urls
        //desc: get current & previous urls
        routeData.urls = {};
        routeData.urls.curr = $location.url().substr(1);
        //...previous url
        if(previous && previous.originalPath){
            //remove matching structure & slashes from url & add params as plain values
            var prevUrl = previous.originalPath.substr(1).replace('/:', '/').replace(':', '');
            if(previous.pathParams){
                angular.forEach(previous.pathParams, function(val, key){
                    prevUrl = prevUrl.replace(key, val);
                });
            }
            routeData.urls.prev = prevUrl;
        }
    
    
        //bind routeData to scope/window...
        $scope.uriSegment = routeData.uriSegment;
        $scope.urls = routeData.urls;
    });
    

    它是如何工作的:

    1.获取当前和以前的网址:

    $scope.urls.curr //shows current url
    $scope.urls.prev //shows previous url
    

    ...如果您的路线定义为 /admin/:userID 并且您在该页面上,则 url 将包含该特定用户 ID,它不会返回参数名称。 /admin/53 将是 /admin/53

    2。从当前 url 中获取特定的 url 段:

    $scope.uriSegment[1]
    

    ...对于像/admin/53 这样的当前网址将打印53

    上面的代码还有很多东西,但我认为这就是你需要的——记住之前的 url。您可以玩路线事件并构建自己的事件。
    我看到你在你的工厂里注入了$routeScope,所以你可以在你的主控制器中添加我的代码,并在每次路由更改时用routeData更新$routeScope,然后你可以这样:

    ...
    previousLocation = $rootScope.urls.prev;
    ...
    

    更多关于路线事件here

    【讨论】:

    • 我想这就是我需要的,我会试一试告诉你。就一个问题。为什么要拆分网址?
    • 在我的应用程序中,我需要知道 url 中的 1st/2nd/etc 段是什么,这就是为什么我有 uriSegment 数组(帖子中的第 2 点)。我有一些案例我想检查if(uriSegment[0] == 'home) { /* do something */ }。您可以删除它,它不会干扰 prev/curr 网址。
    • 做到了。现在我必须弄清楚当登录窗口被关闭时该怎么办,但它并没有对路由更改做出反应,而是点击登录按钮;但那是另一回事。谢谢!
    • 顺便说一下,我是在 routeChangeStart 上做的
    猜你喜欢
    • 1970-01-01
    • 2015-02-01
    • 2021-12-11
    • 2018-03-08
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    相关资源
    最近更新 更多