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'}

];

文档:
https://angular.io/guide/router#setting-up-redirects