使用 Angular2,如何在登录重定向之前重定向到上一个 url
Using Angular2, how to redirect to previous url before login redirect
使用 Angular2 创建单页应用程序,我在自定义 RouterOutlet
中拦截未经身份验证的用户对非 public 路由的访问,并将它们重定向到登录视图。成功登录后,我想将用户重定向到他们最初请求的视图,而不是默认视图。
我注意到 Router
有一个 renavigate()
函数可以导航到最后一条成功的路线,但最后一条成功的路线是 /auth/login
而不是最初请求的 url.
基本上:我如何访问或确定先前请求的 url?
我真的不想求助于传递查询字符串参数,除非我真的必须这样做。理想情况下,作为 Router
组件的一部分访问 history
集合会很好,类似于 backbone.history
!
您可能会在 docs 中为 Location
class 找到您需要的内容。 back()
函数可能会为您完成。
另一种方法是订阅 Location
中的 popstate
事件。 MDN has docs 谈论您期望获得的价值。
class MyCLass {
constructor(private location: Location) {
location.subscribe((val) => {
// do something with the state that's passed in
})
}
}
否则,您可能需要一种服务来跟踪路由器中的更改,以便您可以访问它们。
class MyTrackingService {
constructor(private router: Router) {
router.subscribe((val) => {
// store the routes here so that you can peel them off as needed?
})
}
}
在这种情况下,我正在访问 Router
对象并订阅任何更改,以便我可以跟踪它们。
这对我有用。将它注入到您的主 App 组件的构造函数中,并在 bootstrap 方法中注册它。
页面加载的第一个 val
应该是原来的 URL。
为了提高效率,我立即取消订阅,因为我不想(也许还)不想收听此服务中的后续路由器事件。
将服务注入其他需要originalUrl的地方
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
@Injectable()
export class UrlTrackingService {
public originalUrl: string;
constructor(
private router: Router
) {
let subscription: Subscription = this.router.events.subscribe((val) => {
this.originalUrl = val.url;
subscription.unsubscribe();
});
}
}
- 使用 Auth Guards(实现 CanActivate) to prevent unauthenticated users. See official documentation with examples and this blog。
在auth guard中使用RouterStateSnapshot来捕获请求的URL.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
{
// keep the attempted URL for redirecting
this._loginService.redirectUrl = state.url;
}
重定向到 URL 使用 Router 成功验证(例如在 login.component.ts
中)。例如。 this._router.navigateByUrl(redirectUrl);
P.S。 @MichaelOryl 和@Vitali 的建议会奏效,但我的方式更符合 Angular2 最终版本。
更新示例使用 Angular 2.2.1
将原始 URL 传递给登录组件的 Auth Guard:
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (localStorage.getItem('currentUser')) {
// logged in so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login', { returnUrl: state.url }]);
return false;
}
}
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { AlertService, AuthenticationService } from '../_services/index';
@Component({
moduleId: module.id,
templateUrl: 'login.component.html'
})
登录组件,登录后重定向到上一个/原来的URL:
export class LoginComponent implements OnInit {
model: any = {};
loading = false;
returnUrl: string;
constructor(
private route: ActivatedRoute,
private router: Router,
private authenticationService: AuthenticationService,
private alertService: AlertService) { }
ngOnInit() {
// reset login status
this.authenticationService.logout();
// get return url from route parameters or default to '/'
this.returnUrl = this.route.snapshot.params['returnUrl'] || '/';
}
login() {
this.loading = true;
this.authenticationService.login(this.model.username, this.model.password)
.subscribe(
data => {
// login successful so redirect to return url
this.router.navigate([this.returnUrl]);
},
error => {
// login failed so display error
this.alertService.error(error);
this.loading = false;
});
}
}
有关更多详细信息和工作演示,您可以查看 this post
使用 Angular2 创建单页应用程序,我在自定义 RouterOutlet
中拦截未经身份验证的用户对非 public 路由的访问,并将它们重定向到登录视图。成功登录后,我想将用户重定向到他们最初请求的视图,而不是默认视图。
我注意到 Router
有一个 renavigate()
函数可以导航到最后一条成功的路线,但最后一条成功的路线是 /auth/login
而不是最初请求的 url.
基本上:我如何访问或确定先前请求的 url?
我真的不想求助于传递查询字符串参数,除非我真的必须这样做。理想情况下,作为 Router
组件的一部分访问 history
集合会很好,类似于 backbone.history
!
您可能会在 docs 中为 Location
class 找到您需要的内容。 back()
函数可能会为您完成。
另一种方法是订阅 Location
中的 popstate
事件。 MDN has docs 谈论您期望获得的价值。
class MyCLass {
constructor(private location: Location) {
location.subscribe((val) => {
// do something with the state that's passed in
})
}
}
否则,您可能需要一种服务来跟踪路由器中的更改,以便您可以访问它们。
class MyTrackingService {
constructor(private router: Router) {
router.subscribe((val) => {
// store the routes here so that you can peel them off as needed?
})
}
}
在这种情况下,我正在访问 Router
对象并订阅任何更改,以便我可以跟踪它们。
这对我有用。将它注入到您的主 App 组件的构造函数中,并在 bootstrap 方法中注册它。
页面加载的第一个 val
应该是原来的 URL。
为了提高效率,我立即取消订阅,因为我不想(也许还)不想收听此服务中的后续路由器事件。
将服务注入其他需要originalUrl的地方
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
@Injectable()
export class UrlTrackingService {
public originalUrl: string;
constructor(
private router: Router
) {
let subscription: Subscription = this.router.events.subscribe((val) => {
this.originalUrl = val.url;
subscription.unsubscribe();
});
}
}
- 使用 Auth Guards(实现 CanActivate) to prevent unauthenticated users. See official documentation with examples and this blog。
在auth guard中使用RouterStateSnapshot来捕获请求的URL.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { // keep the attempted URL for redirecting this._loginService.redirectUrl = state.url; }
重定向到 URL 使用 Router 成功验证(例如在
login.component.ts
中)。例如。this._router.navigateByUrl(redirectUrl);
P.S。 @MichaelOryl 和@Vitali 的建议会奏效,但我的方式更符合 Angular2 最终版本。
更新示例使用 Angular 2.2.1
将原始 URL 传递给登录组件的 Auth Guard:
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (localStorage.getItem('currentUser')) {
// logged in so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login', { returnUrl: state.url }]);
return false;
}
}
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { AlertService, AuthenticationService } from '../_services/index';
@Component({
moduleId: module.id,
templateUrl: 'login.component.html'
})
登录组件,登录后重定向到上一个/原来的URL:
export class LoginComponent implements OnInit {
model: any = {};
loading = false;
returnUrl: string;
constructor(
private route: ActivatedRoute,
private router: Router,
private authenticationService: AuthenticationService,
private alertService: AlertService) { }
ngOnInit() {
// reset login status
this.authenticationService.logout();
// get return url from route parameters or default to '/'
this.returnUrl = this.route.snapshot.params['returnUrl'] || '/';
}
login() {
this.loading = true;
this.authenticationService.login(this.model.username, this.model.password)
.subscribe(
data => {
// login successful so redirect to return url
this.router.navigate([this.returnUrl]);
},
error => {
// login failed so display error
this.alertService.error(error);
this.loading = false;
});
}
}
有关更多详细信息和工作演示,您可以查看 this post