Angular 2 Routing Does Not Work When Deploying to Http Server

I am going to develop a simple Angular 2 application. I created a routing project using the Angular CLI and adding several components to the application using the "ng generate component" command. Then I specified the routing in app-routing.module.ts as follows.

 import {NgModule} from '@ angular / core';  import {Routes, RouterModule} from '@ angular / router';  import {HomeComponent} from './home/home.component';  import {AboutComponent} from './about/about.component';  import {UserComponent} from './user/user.component';  import {ErrorComponent} from './error/error.component';  import {SpecialpageComponent} from './specialpage/specialpage.component';  const routes: Routes = [{path: '', component: HomeComponent}, {path: 'about', component: AboutComponent}, {path: 'user', component: UserComponent}, {path: 'specialpage', component: SpecialpageComponent}, {path: '**', component: ErrorComponent}];  @NgModule ({imports: [RouterModule.forRoot (routes)], exports: [RouterModule], providers: []}) export class AppRoutingModule {} 

app.module.ts is as follows.

  import {BrowserModule} from '@ angular / platform-browser';
 import {NgModule} from '@ angular / core';
 import {FormsModule} from '@ angular / forms';
 import {HttpModule} from '@ angular / http';
 import {AppRoutingModule} from './app-routing.module';

 import {AppComponent} from './app.component';
 import {HomeComponent} from './home/home.component';
 import {AboutComponent} from './about/about.component';
 import {ErrorComponent} from './error/error.component';
 import {UserComponent} from './user/user.component';
 import {SpecialpageComponent} from './specialpage/specialpage.component';

 @NgModule ({
   declarations: [
     AppComponent
     HomeComponent,
     AboutComponent,
     ErrorComponent,
     UserComponent
     Specialpagecompponent
   ],
   imports: [
     BrowserModule,
     FormsModule,
     HttpModule,
     AppRoutingModule
   ],
   providers: [],
   bootstrap: [AppComponent]
 })
 export class AppModule {}

I have not added any changes to other components. Then I deployed the application using the "ng serve" command, and the application works fine with links. For example: http: // localhost: 4200 / about

enter image description here

But when I deploy the project to the http server, the links do not work as expected. I deployed the application using the command "http-server./dist" and the application is perfectly deployed, but the links do not work. When I go to http: // localhost: 4200 / about ', it gives a 404 error.

enter image description here

Am I doing something wrong? Why does "ng-serve" work and "http-server" does not work?

Any help would be greatly appreciated. Thank you in advance.

I uploaded my project to github .

+27
source share
16 answers

This problem is solved by implementing a HashLocationStrategy which adds # to all your routes. This is achieved by adding HashLocationStrategy to AppModule providers .

  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}], 

and add the appropriate import

  import { HashLocationStrategy, LocationStrategy } from '@angular/common'; 

This will solve your problem.

And if you do not want to use HashLocationStrategy , you can use PahtLocationStrategy , and your Angular application will not display Hash in the URL. For more information on this, check the official link: https://angular.io/api/common/PathLocationStrategy

+24
source

This is because the http server does not support a backup , such as a lite-server or web pack-dev server. That's why it shows 404 not found . There are two solutions to solve this problem:

  • you can use HashLocationStrategy as above.
  • If you are deploying it on an Apache or IIS server, you can simply add the configurations as indicated here !

Note. For development, you can use the Lite server.

Hope this helps you.

+12
source

This will happen because he will find a page about which is not inside, therefore 404. Possible options:

  • If you want to go with an http server, use a proxy server that redirects everything to http: // localhost: your-port .

    Option: -P or --proxy Proxies all requests that cannot be resolved locally with the given URL. for example: -P http://someurl.com

  • Do not use expression at all. Build your own http server using express and redirect everything to index.html

    Assuming the publication is your folder in which you save all the transferred things.

     var express = require('express'); var app = express(); var path = __dirname + '/public'; var port = 8080; app.use(express.static(path)); app.get('*', function(req, res) { res.sendFile(path + '/index.html'); }); app.listen(port); 
+6
source

I solved this problem by adding this to the AppModule providers:

 providers: [{provide: LocationStrategy, useClass: PathLocationStrategy}] 

and import

 import { PathLocationStrategy, LocationStrategy } from '@angular/common'; 

Then I created .htaccess:

 RewriteEngine On # If an existing asset or directory is requested go to it as it is RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] # If the requested resource doesn't exist, use index.html RewriteRule ^ /index.html 

Everything works fine without # in the url :)

+5
source

It will be solved in this way:

Case-1: for version less than Angular 5.1

1) Use HashLocationStrategy as follows: In the AppModule, follow these steps.

1.1) import { HashLocationStrategy, LocationStrategy } from '@angular/common';

1.2) providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]

Case 2: for version equal to or greater than Angular 5.1

2.1) Angular introduced this onSameUrlNavigation property to overcome the upgrade problem on the server.

2.2) Add onSameUrlNavigation in RouterModule.forRoot to the import array.

a) In the main routing module of application i, e app.routing.module.ts / app.routing.ts adds the property

See below:

 @ngModule({ imports: [ RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'}) ], exports: [RouterModule], }); 

Hope this helps someone.

+2
source

For Apache server:

on production servers

Add or create a ".htaccess" file in the project root, add a rewrite rule to the .htaccess file, as shown

 RewriteEngine On # If an existing asset or directory is requested go to it as it is RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] # If the requested resource doesn't exist, use index.html RewriteRule ^ /index.html 
+1
source

If you, like me, do not want to make any changes to the code, just use instead:

https://www.npmjs.com/package/angular-http-server

+1
source

For Apache Server

  • Create .htaccess file name
  • Edit this file and write index.html instead of index.php
  • For those who do not have any code, you can write the code below in your .htaccess file: RewriteEngine On # If an existing asset or directory is requested go to it as it is RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] # If the requested resource doesn't exist, use index.html RewriteRule ^/index.html

  • This code may not work for the SSL certificate - contact your hosting provider OR visit https://httpd.apache.org/docs/current/howto/htaccess.html to refer to the documentation.

0
source

According to the documentation at https://angular.io/guide/deployment (Apache, you can also look for nginx). You need to tell the index.html server using the .htaccess file as

 RewriteEngine On # If an existing asset or directory is requested go to it as it is RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] # If the requested resource doesn't exist, use index.html 

RewriteRule ^ / index.html

0
source

You should try to specify the URL in the assembly since the application was initialized:

 Ng build --prod --base-href="http://your.url.com/subdirectory/etc" 
0
source

The exact reason this particular problem occurs is related to your server settings.

Therefore, when you implement the application, you must take certain steps. One of the important steps is to highlight a specific segment of your path, for example: http: // domain-name / main, where main, which is a path segment, should be used as an identifier in your server settings, say, your server.js or app.js when it comes to the backend of a host or webconfig file for deploying IIS and Tomcat.

The reason for marking a specific segment is that when the server receives any request with this particular segment + additional, you redirect it to your application in www or in the public folder to start the corner router.

This process is known as URL rewriting . Therefore, if the web server or application server, depending on the size of the application, is not under your control, use hashLocationStratergy, otherwise it is always useful to use pathLocationStartergy, as this is useful when tracking history and other aesthetic benefits and performance.

To learn more about this you can visit these links:

For IIS : https://blog.angularindepth.com/deploy-an-angular-application-to-iis-60a0897742e7

0
source

Add a dot to your href lines.

Correct

 <base href="./home"> 

Wrong

 <base href="/home"> 

http://www.wisdomofjim.com/blog/solved-problems-with-resource-loading-failures-when-deploying-angular-2-webapps-live

0
source
 export const routes: Routes =[ **{ path: '', redirectTo: '/', pathMatch: 'full'},** { path: 'about', component: AboutComponent}, { path: 'user', component: UserComponent}, { path: 'specialpage', component: SpecialpageComponent}, { path: '**', component: ErrorComponent} ]; 

Take a look at the contents of blockquote. And then you give the name "HttpModule" to providers:[] in app.module.ts

Thanks.

-1
source

You can do this while registering your RouterModule.forRoot, you can pass a second object with the property {useHash: true}, as shown below:

 import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {AppComponent} from './app.component'; import {appRoutes} from './app.routes'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule], RouterModule.forRoot(appRoutes , {useHash: true})], providers: [], bootstrap: [AppComponent], }) export class AppModule {} 
-1
source

Change index.html

 <base href="/"> to <base href="./"> 

Since we use Tomcat, we mentioned this (.) For routing based on this (/) Just like http-server

I mean, you are working fine as soon as you saw http://localhost:4200/

but by starting the server, you put your assembly in (dist) in webapps

therefore it comes like

 http://localhost:8080/dist/ 

so you need to add <base href="./">

I think this is a problem because you can solve it.

-1
source

in the project folder create a .htaccess file and then write

 RewriteEngine On RewriteCond %{HTTP_HOST} ^example\.com$ [NC] RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.html [L] 

follow this link: https://angular.io/guide/deployment

-1
source

Source: https://habr.com/ru/post/1267001/


All Articles