在 Angular 请求拦截器上获取上一个 URL
Get previous URL on Angular request interceptor
我正在实施 angular 页面范围 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);
},
我希望这一行给我“被调用者”路径,但它实际上给了我请求的路径(angular 在执行请求之前已经更改了它)。
路线提供商
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/admin', {
templateUrl: "/admin"
})
.otherwise({ redirectTo: '/' });
}])
这个顽皮的小男孩在请求之前改变了我的路径。我想我可以在这里做一些关于 resolve 的事情,但我觉得这没有用,因为它会完全破坏封装,迫使我每次调用任何受保护的资源时都要 resolve,所以我可以将当前路径传递给我的某些服务授权应用
那么,如何从拦截器或 auth 应用程序中的某些服务中获取先前的路径,而不是从路由提供程序配置中明确发送它?
你为什么不观察 $on
路由更改事件并将你的 current/previous 路径绑定到 $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.获取当前和以前的 url:
$scope.urls.curr //shows current url
$scope.urls.prev //shows previous url
...如果您的路由定义为 /admin/:userID
并且您在该页面上,url 将包含该特定用户 ID,它不会 return 参数名称. /admin/53
将是 /admin/53
.
2。从当前 url:
中获取特定的 url 片段
$scope.uriSegment[1]
... 对于当前 url 像 /admin/53
将打印 53
上面的代码中还有很多东西,但我认为这就是你需要的——记住前面的url。您可以玩转路线事件并构建您自己的路线事件。
我看到你在你的工厂中注入了 $routeScope
,所以你可以在你的主控制器中添加我的代码,并在每次路由更改时将 $routeScope
更新为 routeData
然后你可以这样做:
...
previousLocation = $rootScope.urls.prev;
...
关于路线事件的更多信息here。
我正在实施 angular 页面范围 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);
},
我希望这一行给我“被调用者”路径,但它实际上给了我请求的路径(angular 在执行请求之前已经更改了它)。
路线提供商
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/admin', {
templateUrl: "/admin"
})
.otherwise({ redirectTo: '/' });
}])
这个顽皮的小男孩在请求之前改变了我的路径。我想我可以在这里做一些关于 resolve 的事情,但我觉得这没有用,因为它会完全破坏封装,迫使我每次调用任何受保护的资源时都要 resolve,所以我可以将当前路径传递给我的某些服务授权应用
那么,如何从拦截器或 auth 应用程序中的某些服务中获取先前的路径,而不是从路由提供程序配置中明确发送它?
你为什么不观察 $on
路由更改事件并将你的 current/previous 路径绑定到 $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.获取当前和以前的 url:
$scope.urls.curr //shows current url
$scope.urls.prev //shows previous url
...如果您的路由定义为 /admin/:userID
并且您在该页面上,url 将包含该特定用户 ID,它不会 return 参数名称. /admin/53
将是 /admin/53
.
2。从当前 url:
中获取特定的 url 片段$scope.uriSegment[1]
... 对于当前 url 像 /admin/53
将打印 53
上面的代码中还有很多东西,但我认为这就是你需要的——记住前面的url。您可以玩转路线事件并构建您自己的路线事件。
我看到你在你的工厂中注入了 $routeScope
,所以你可以在你的主控制器中添加我的代码,并在每次路由更改时将 $routeScope
更新为 routeData
然后你可以这样做:
...
previousLocation = $rootScope.urls.prev;
...
关于路线事件的更多信息here。