Angular 部署到 tomcat 9 (Ubuntu 18.04) 时路由不起作用

Angular routing not working when deployed to tomcat 9 (Ubuntu 18.04)

我在自己的 PC 上编写了一个 angular 项目,当我 运行 在本地使用命令 ng serve 时一切正常。现在我想把它部署在虚拟机(我学校提供)上 tomcat 上,因为我的项目需要 public。

我创建了一个 git 存储库并在 VM 上下载了 angular 项目。按照教程在 tomcat 中部署应用程序,它仅包含 2 个步骤:

  1. 运行 ng build --base-href=/angular/ 生成一些文件
  2. 将生成的文件复制到 tomcat 的 /webapps 子文件夹

但它没有按预期工作。在我看来,路由似乎有问题。

这是我的路由模块:

const appRoutes: Routes = [
  {path: 'coachPortal', component: CoachPortalComponent},
  {path: 'userPortal', component: UserPortalComponent},
  {path: 'users', component: UsersComponent},
  {path: 'userDetails/:id', component: UserDetailsComponent},
  {path: 'mySessions', component: MySessionsComponent},
  {path: '', redirectTo: '/coachPortal', pathMatch: 'full'},
  {path: '**', component: CoachPortalComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

为了在路线之间导航,我使用这个旧的简单代码:window.location.href = '/users';
当我在我的电脑上本地 运行 时,这就像一个魅力。

但我猜测在 tomcat 上部署后它不再工作的原因是因为 tomcat 添加了前缀 angular/.
当 运行 在我的电脑上本地时, url 是 localhost:4200/{componenturl}.
但是在 VM 上它是 x.x.x.x:8080/angular/{componenturl}

但是由于路由重定向,我收到了 404 错误。当我第一次访问根 url x.x.x.x:8080/angular 时,它与规则 {path: '', redirectTo: '/coachPortal', pathMatch: 'full'} 相匹配。并加载 coachPortal 组件, 甚至将 url 更改为 angular/coachPortal。但是刷新页面或者手动输入angular/coachPortal会出现404错误。所有其他链接也不起作用。

另外,在 coachPortal 上,我有一个带有 src ../../../assets/logo.png 的图像,它显然不会加载,因为 webapps 文件夹中生成的文件具有不同的文件夹结构...我该如何解决这个问题?图片直接在assets文件夹下。

我的理解是,当您尝试导航到通常通过 Angular 路由解析的虚拟子目录时,部署时您的网络服务器正在寻找 'coachportal' 的实际目录,它不存在,所以 returns 一个 404。如果路由已经通过你的应用程序导航到(通过导航按钮等)Angular 路由器将解析它并调出虚拟 sub-directory .您的网络服务器正在阻止路由到达 Angular 路由器来解决它。您的网络服务器会检查是否存在实际的文件夹或文件,如果没有该名称的文件或文件夹,则重定向到您的根目录以处理路由。对于我在 IIS 上部署的 Web 项目,我包含一个包含以下代码的 web.config 文件:

<configuration>
    <system.webServer>
      <rewrite>
        <rules>
          <rule name="Angular" stopProcessing="true">
            <match url=".*" />
            <conditions logicalGrouping="MatchAll">
              <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
              <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            </conditions>
            <action type="Rewrite" url="/" />
          </rule>
        </rules>
      </rewrite>
    </system.webServer>
</configuration>

从这个 post: 我不确定它是否适用于您的部署设置,但至少应该让您深入了解可能发生的事情。

对于您的资产文件夹,删除相对目录的 ../s 并将其保留为 assets/logo.png 它应该可以正确处理。你可以在本地测试它。

编辑:为清楚起见更改了一些内容

您可以尝试使用useHash: true。对我来说它的工作。

示例:

@NgModule({
    imports: [RouterModule.forRoot(routes, { useHash: true })],
    exports: [RouterModule],
})
VM 上的

和 url 将是 x.x.x.x:8080/angular/#/{componenturl}

我也遇到了这个问题,求一个简单的方法。也许它会帮助别人。 使用 apache-tomcat-7.0.55 和 angular 11。其他版本未测试。

只是基于@Erikher 的回答,还有一些事情要做:

  • 首先RouterModule.forRoot(routes, {useHash: true})

  • *(可能不需要)*:providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],

  • third: 将 index.html 中的 base-href'/' 更改为 '#'

那对我有用。