Angular - 浏览器刷新时,显示根组件而不是路由中定义的组件
Angular - On browser refresh, the root component is displayed instead of the one defined in routes
我的 Angular 应用程序的浏览器刷新有问题。
当我通过刷新浏览器或键入 URL 重新加载页面时,应用程序始终转到“/”路径。
我尝试了很多东西,但 none 奏效了。
当我处于实时模式(本地开发服务器上的 ng 服务)或生产服务器时会出现问题。
这是我的 nginx 配置:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
expires $expires;
gzip on;
}
这是我的应用程序-routing.module.ts :
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './components/login/login.component';
import { UserProfileComponent } from './components/user-profile/user-profile.component';
import { AuthGuard } from './guards/auth.guard';
import {DashboardComponent} from './components/dashboard/dashboard.component';
import {ProjectsComponent} from './components/projects/projects.component';
import {TeamComponent} from './components/team/team.component';
import {RentalsComponent} from './components/rentals/rentals.component';
import {MessagesComponent} from './components/messages/messages.component';
import {SettingsComponent} from './components/settings/settings.component';
import {RouteconfigGuard} from './guards/routeconfig.guard';
import {ProjectAddComponent} from './components/projects/project-add/project-add.component';
import {TeamAddComponent} from './components/team/team-add/team-add.component';
// tslint:disable-next-line:max-line-length
import {SettingsCustomFieldsEditComponent} from './components/settings/settings-custom-fields/settings-custom-fields-edit/settings-custom-fields-edit.component';
const routes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full'},
{ path: 'login', component: LoginComponent},
{ path: 'testroute', component: SettingsComponent},
{ path: 'profile', component: UserProfileComponent, canActivate: [AuthGuard] },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'projects', component: ProjectsComponent, canActivate: [AuthGuard] },
{ path: 'team', component: TeamComponent, canActivate: [AuthGuard, RouteconfigGuard] },
{ path: 'team/add', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'team/edit/:id', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'rentals', component: RentalsComponent, canActivate: [AuthGuard] },
{ path: 'messages', component: MessagesComponent, canActivate: [AuthGuard] },
{ path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
{ path: 'projects/add', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id/:tab', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'settings/custom-fields/:field', component: SettingsCustomFieldsEditComponent, canActivate: [AuthGuard] },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
这是我的 AuthGuard 文件:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
public authService: AuthService,
public router: Router
) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (this.authService.isLoggedIn !== true) {
this.router.navigate(['/']);
}
return true;
}
}
这是我的 auth.service 文件:
import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {HttpClient} from '@angular/common/http';
import {Router} from '@angular/router';
import {environment as env} from '../../environments/environment';
import {LoaderService} from './loader.service';
import {MenuService} from './menu.service';
import {TokenService} from './token.service';
@Injectable({
providedIn: 'root'
})
export class AuthService {
signInEndpoint = env.mainApiEndpoint + '/login';
badCredentials = new BehaviorSubject<boolean>(false);
userLogged = new BehaviorSubject<boolean>(false);
constructor(
private http: HttpClient,
public router: Router,
public loaderService: LoaderService,
public menuService: MenuService,
public tokenService: TokenService
) {
}
// Sign-in
signIn(user) {
this.loaderService.show();
this.badCredentials.next(false);
return this.http.post<any>(this.signInEndpoint, user)
.subscribe(
(res) => this.manageLoginSuccess(res),
(err) => this.setInvalidCredentials(err)
);
}
manageLoginSuccess(res: any) {
this.tokenService.setToken(res.token);
this.userLogged.next(true);
this.loaderService.hide();
this.router.navigate([this.menuService.homepage]);
}
setInvalidCredentials(err) {
this.loaderService.hide();
this.badCredentials.next(true);
}
get isLoggedIn(): boolean {
const authToken = this.tokenService.getToken();
const isLogged = authToken !== null;
if (isLogged) {
this.userLogged.next(true);
}
return isLogged;
}
doLogout() {
const removeToken = this.tokenService.removeToken();
if (removeToken == null) {
this.userLogged.next(false);
this.router.navigate(['login']);
}
}
}
我试图更改 canActivate 实现,使其始终 returns 正确,但它不起作用。
即使我删除了对路由文件的 canActivate 调用,它也不起作用。
如果我去 /testroute(在路线中定义),它不起作用。
我做错了什么?
非常感谢您的帮助!
尝试更改此设置(路径的顺序很重要):
const routes: Routes = [
{ path: 'login', component: LoginComponent},
{ path: 'testroute', component: SettingsComponent},
{ path: 'profile', component: UserProfileComponent, canActivate: [AuthGuard] },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'projects', component: ProjectsComponent, canActivate: [AuthGuard] },
{ path: 'team', component: TeamComponent, canActivate: [AuthGuard, RouteconfigGuard] },
{ path: 'team/add', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'team/edit/:id', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'rentals', component: RentalsComponent, canActivate: [AuthGuard] },
{ path: 'messages', component: MessagesComponent, canActivate: [AuthGuard] },
{ path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
{ path: 'projects/add', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id/:tab', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'settings/custom-fields/:field', component: SettingsCustomFieldsEditComponent, canActivate: [AuthGuard] },
{ path: '', redirectTo: '/login', pathMatch: 'full'}
];
我的 Angular 应用程序的浏览器刷新有问题。 当我通过刷新浏览器或键入 URL 重新加载页面时,应用程序始终转到“/”路径。
我尝试了很多东西,但 none 奏效了。
当我处于实时模式(本地开发服务器上的 ng 服务)或生产服务器时会出现问题。
这是我的 nginx 配置:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
expires $expires;
gzip on;
}
这是我的应用程序-routing.module.ts :
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './components/login/login.component';
import { UserProfileComponent } from './components/user-profile/user-profile.component';
import { AuthGuard } from './guards/auth.guard';
import {DashboardComponent} from './components/dashboard/dashboard.component';
import {ProjectsComponent} from './components/projects/projects.component';
import {TeamComponent} from './components/team/team.component';
import {RentalsComponent} from './components/rentals/rentals.component';
import {MessagesComponent} from './components/messages/messages.component';
import {SettingsComponent} from './components/settings/settings.component';
import {RouteconfigGuard} from './guards/routeconfig.guard';
import {ProjectAddComponent} from './components/projects/project-add/project-add.component';
import {TeamAddComponent} from './components/team/team-add/team-add.component';
// tslint:disable-next-line:max-line-length
import {SettingsCustomFieldsEditComponent} from './components/settings/settings-custom-fields/settings-custom-fields-edit/settings-custom-fields-edit.component';
const routes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full'},
{ path: 'login', component: LoginComponent},
{ path: 'testroute', component: SettingsComponent},
{ path: 'profile', component: UserProfileComponent, canActivate: [AuthGuard] },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'projects', component: ProjectsComponent, canActivate: [AuthGuard] },
{ path: 'team', component: TeamComponent, canActivate: [AuthGuard, RouteconfigGuard] },
{ path: 'team/add', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'team/edit/:id', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'rentals', component: RentalsComponent, canActivate: [AuthGuard] },
{ path: 'messages', component: MessagesComponent, canActivate: [AuthGuard] },
{ path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
{ path: 'projects/add', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id/:tab', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'settings/custom-fields/:field', component: SettingsCustomFieldsEditComponent, canActivate: [AuthGuard] },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
这是我的 AuthGuard 文件:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
public authService: AuthService,
public router: Router
) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (this.authService.isLoggedIn !== true) {
this.router.navigate(['/']);
}
return true;
}
}
这是我的 auth.service 文件:
import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {HttpClient} from '@angular/common/http';
import {Router} from '@angular/router';
import {environment as env} from '../../environments/environment';
import {LoaderService} from './loader.service';
import {MenuService} from './menu.service';
import {TokenService} from './token.service';
@Injectable({
providedIn: 'root'
})
export class AuthService {
signInEndpoint = env.mainApiEndpoint + '/login';
badCredentials = new BehaviorSubject<boolean>(false);
userLogged = new BehaviorSubject<boolean>(false);
constructor(
private http: HttpClient,
public router: Router,
public loaderService: LoaderService,
public menuService: MenuService,
public tokenService: TokenService
) {
}
// Sign-in
signIn(user) {
this.loaderService.show();
this.badCredentials.next(false);
return this.http.post<any>(this.signInEndpoint, user)
.subscribe(
(res) => this.manageLoginSuccess(res),
(err) => this.setInvalidCredentials(err)
);
}
manageLoginSuccess(res: any) {
this.tokenService.setToken(res.token);
this.userLogged.next(true);
this.loaderService.hide();
this.router.navigate([this.menuService.homepage]);
}
setInvalidCredentials(err) {
this.loaderService.hide();
this.badCredentials.next(true);
}
get isLoggedIn(): boolean {
const authToken = this.tokenService.getToken();
const isLogged = authToken !== null;
if (isLogged) {
this.userLogged.next(true);
}
return isLogged;
}
doLogout() {
const removeToken = this.tokenService.removeToken();
if (removeToken == null) {
this.userLogged.next(false);
this.router.navigate(['login']);
}
}
}
我试图更改 canActivate 实现,使其始终 returns 正确,但它不起作用。 即使我删除了对路由文件的 canActivate 调用,它也不起作用。 如果我去 /testroute(在路线中定义),它不起作用。
我做错了什么?
非常感谢您的帮助!
尝试更改此设置(路径的顺序很重要):
const routes: Routes = [
{ path: 'login', component: LoginComponent},
{ path: 'testroute', component: SettingsComponent},
{ path: 'profile', component: UserProfileComponent, canActivate: [AuthGuard] },
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: 'projects', component: ProjectsComponent, canActivate: [AuthGuard] },
{ path: 'team', component: TeamComponent, canActivate: [AuthGuard, RouteconfigGuard] },
{ path: 'team/add', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'team/edit/:id', component: TeamAddComponent, canActivate: [AuthGuard] },
{ path: 'rentals', component: RentalsComponent, canActivate: [AuthGuard] },
{ path: 'messages', component: MessagesComponent, canActivate: [AuthGuard] },
{ path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
{ path: 'projects/add', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'project/edit/:id/:tab', component: ProjectAddComponent, canActivate: [AuthGuard] },
{ path: 'settings/custom-fields/:field', component: SettingsCustomFieldsEditComponent, canActivate: [AuthGuard] },
{ path: '', redirectTo: '/login', pathMatch: 'full'}
];