简体   繁体   中英

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

I coded an angular project on my own PC, everything worked fine when I ran it locally with the command ng serve . Now I want to deploy it on tomcat on a VM (provided by my school) because my project needs to be public.

I created a git repository and downloaded the angular project on the VM. Followed a tutorial to deploy the app in tomcat, which simply consisted of 2 steps:

  1. Run ng build --base-href=/angular/ to generate some files
  2. Copy the generated files to tomcat's /webapps subfolder

But it does not work as intended. To me it seems like there's an issue with routing.

Here's my routing module:

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

To navigate between routes, I use this old simple code: window.location.href = '/users';
This worked like a charm when I ran it locally on my pc.

But I'm guessing the reason why it's not working anymore after deploying on tomcat is because tomcat adds the prefix angular/ .
When running locally on my pc the urls were localhost:4200/{componenturl} .
But on the VM it's xxxx:8080/angular/{componenturl}

But because of the routing redirects I am getting 404 errors. When I first visit the root url xxxx:8080/angular , it matches with the rule {path: '', redirectTo: '/coachPortal', pathMatch: 'full'} . and loads the coachPortal component and even changes the url to angular/coachPortal . But refreshing the page or manually entering angular/coachPortal gives a 404 error. And all other links don't work either.

Also on the coachPortal I have an image with src ../../../assets/logo.png and it obviously doesn't load because of how the generated files in webapps folder have different folder structure... How can I fix this? The image is directly under assets folder.

You can try use useHash: true . For me its working.

Example:

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

and url on the VM will be xxxx:8080/angular/#/{componenturl}

My understanding is that when you try to navigate to a virtual sub directory that is usually resolved via Angular Routing, when it is deployed your webserver is looking for an actual directory of 'coachportal', which doesn't exist so returns a 404. If the route had been navigated to through your app (by navigation buttons etc.) Angular Router would resolve it and bring up the virtual sub-directory. Your webserver is stopping the route from getting to Angular Router to resolve it. Your webserver checks to see if there is an actual folder or file and then redirects to your root to handle the routing if there is no file or folder with that name. For web projects I have deployed on IIS I include a web.config file with the following code:

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

from this post: Routing in Angular 7 running in subfolder not working correctly I'm not sure if it will work with your deployment setup, but should at least give you insight into what may be going on.

For your assets folder remove the ../ s for a relative directory and just leave it as assets/logo.png it should handle this correctly. you can test it locally.

EDIT: changed some things for clarity

I also met this problem, and just find an easy way. Maybe it will help others. with apache-tomcat-7.0.55 and angular 11. with other versions not tested.

just based on @Erikher 's answer and something more to be done:

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

  • second *(may not need)*: providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],

  • third : change base-href in index.html from '/' to '#'

Then it works for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM