Reputation: 3160
I have deployed an angular application with lazy loading. The application works perfectly when hosted on Github.io domain but I am getting an error when I deployed the app on tomcat server using mobaxterm. When the page reloads or refreshes the app loses the routing state and throws a 404 error.
HTTP Status 404 - /enquiry
type Status report
message /enquiry
description The requested resource is not available.
Apache Tomcat/7.0.72
Console-Log:: GET http://appv2.proctur.com/enquiry/addEnquiry 404 (Not Found) Navigated to http://appv2.proctur.com/enquiry/addEnquiry
If I do not refresh the page and use the app in one go then its OK, just fail to understand what the issue is on refresh.
PS:: this is my first time hosting an angular application on tomcat server if I made any silly mistake please let me know.
For better clarification, I am adding the routing.module.ts where I lazy load the modules. This is imported into app.module.ts::
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forRoot([
{ path: '', redirectTo: '/authPage', pathMatch: 'full' },
{ path: 'authPage', loadChildren: 'app/components/auth-page/auth-page.module#AuthPageModule' },
{ path: 'course', loadChildren: 'app/components/course/course.module#CourseModule' },
{ path: 'enquiry', loadChildren: 'app/components/enquiry/enquiry.module#EnquiryModule' },
{ path: 'student', loadChildren: 'app/components/students/student.module#StudentModule' },
])
],
exports: [
RouterModule
]
})
export class AppRoutingModule {
}
Upvotes: 20
Views: 19820
Reputation: 5545
I solved my problem by config web.xml
inside Angular Project
1 - Create Folder WEB-INF
inside src
angular folder and add web.xml
with below code :
<web-app>
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
</web-app>
2 - Modify angular.json
search on "assets"
and add "src/WEB-INF"
as below :
"assets": [
"src/favicon.ico",
"src/assets",
"src/WEB-INF"
],
3 - Build angular project with this command :
ng build --prod
4 - Modify <base href="/">
in index.html
after build it in dist/index.html
to be <base href="./">
5 - Restart Tomcat Server
Upvotes: 6
Reputation: 9487
This also working if you defind 404 page Web.xml file
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
So refresh page http://appv2.proctur.com/enquiry/addEnquiry 404 error found redirect to index.html and call your actual route in anguler side then it will go to correct location.
Upvotes: 9
Reputation: 3011
Angular (2+) supports two types of Routing Strategies – HashLocationStrategy
and PathLocationStrategy
. PathLocationStrategy
is the default configuration when you build an application using the angular CLI. PathLocationStrategy
is having lot of advantages over the HashLocationStrategy
and is the recommended configuration which is discussed in the docs here.
The drawback of PathLocationStrategy
is that it needs specific configuration to be done at the server side. If this configuration is not done at the server end, then it leads to 404
when deep links are accessed directly. Also this configuration depends on which server is being used.
For fixing the deep link issue when deploying angular application (with PathLocationStrategy routing) on apache tomcat server (8, 9) -
server.xml -
...
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
...
</Host>
...
rewrite.config - (note - /hello/ is the context path of the angular app on tomcat)
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/hello/(.*) /hello/index.html
I have documented this issue in my article - Fixing deep linking issue – Deploying angular application on Tomcat server
Upvotes: 9
Reputation: 3315
The previous answer is correct, but we don't really need hashes in our url-s. The problem is as follows: For example, if we have a route named '/users/all', and navigate there from '/' inside our app, then it is perfectly okay, as Angular's own router will resolve the route and display the page, but if we go directly to that route, e.g. by typing in the url in the browser's address bar, we'll get 404, Why? Because your server (tomcat in your case) will try to find a folder named 'users' and an 'all' file inside it, which, obviously, is non-existent, as it is merely an Angular route, not an actual file inside your server's system. But you can configure your server in a way, the it will fallback to your index.html
file, which contains the app, so the pages will be displayed correctly (in the case of our example, the server will return index.html
, then the Angular app will run and resolve the route).
Read more about this here.
Upvotes: 11
Reputation: 1040
When angular app load first-time url will serve from a server. when you navigate pages then it handled at client side. when you refresh the page then request will go to server(tomcat or node). but that routed url doesn't exist on server. then comes 404 error. you can resolve by HashLocationStrategy, added {useHash: true} object in routing configuration ie.
RouterModule.forRoot(routes, {useHash: true})
More details:- https://codecraft.tv/courses/angular/routing/routing-strategies/#_hashlocationstrategy
Upvotes: 24