Angular 2 Routing Does Not Work When Deployed to H

2020-02-08 00:55发布

I am going to develop a simple Angular 2 application. I have created a project with routing, using Angular CLI and added several components to the app using 'ng generate component ' command. Then I specified routing in the app-routing.module.ts as following.

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

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,
    SpecialpageComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

I have not added any modifications for the other components. Then I deployed the application using 'ng serve' command and the app works fine with the links. Eg: http://localhost:4200/about

enter image description here

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

enter image description here

Am I doing anything wrong? Why 'ng-serve' works and 'http-server' does not work?

Any help would be appreciated. Thanks in advance.

I have uploaded my project to github.

18条回答
再贱就再见
2楼-- · 2020-02-08 01:13

It will happen because it goes to find a page about which is not there inside at all hence 404. Possible options:

  1. If you want to go with http-server then use a proxy which will redirect everything to http://localhost:your-port.

    Option: -P or --proxy Proxies all requests which can't be resolved locally to the given url. e.g.: -P http://someurl.com

  2. Don't use express at all. Create your own http-server using express & Redirect everything to index.html

    Assuming public is your folder where u keep all transpiled 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);
    
查看更多
做个烂人
3楼-- · 2020-02-08 01:13

For Apache server:

in the Production servers

Add or create ".htaccess" file into 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
查看更多
淡お忘
4楼-- · 2020-02-08 01:13

As per the documentation at https://angular.io/guide/deployment (Apache, you could also look for nginx) You need to point the server to index.html 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

查看更多
姐就是有狂的资本
5楼-- · 2020-02-08 01:14

I also faced this issue and found a solution that does not require HashLocationStrategy solution.

Issue is, a server like tomcat looks for a actual folder (for eg : /about ) which does not exist in angular app, as its a single page application. So every request needs to be redirected to index.html.

Easiest way to fix this issue is to add the following java class and override addResourceHandlers() method like below:

@Configuration
class WebMVCCustomConfiguration implements WebMvcConfigurer {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**").addResourceLocations("classpath:static").resourceChain(true)
            .addResolver(new PathResourceResolver() {
                @Override
                protected Resource getResource(String resourcePath, Resource location) {
                    String path = "static/";
                    path += (resourcePath.contains(".") && !resourcePath.equals("index.html")) ? resourcePath : "index.html";

                    Resource resource = new ClassPathResource(path);
                    return resource.exists() ? resource : null;
                }
            });
    }
  }

This will fix all the issues and this solution does not exist anywhere.

查看更多
【Aperson】
6楼-- · 2020-02-08 01:18

It will be solved in this way:

Case-1: For version less than Angular 5.1

1) Use HashLocationStrategy like mentioned below: In AppModule do the following.

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

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

Case-2: For version equal or more than Angular 5.1

2.1) Angular has introduced this property onSameUrlNavigation for overcoming refresh issue on the server.

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

a) In Application main routing module, i,e app.routing.module.ts / app.routing.ts add the property

See below:

@ngModule({

    imports: 
    [
       RouterModule.forRoot(routes, {onSameUrlNavigation: ‘reload’})
    ],

    exports: [RouterModule],
 });

Hope it help somebody.

查看更多
对你真心纯属浪费
7楼-- · 2020-02-08 01:23
export const routes: Routes =[
   **{ path: '', redirectTo: '/', pathMatch: 'full'},**
     { path: 'about', component: AboutComponent},
     { path: 'user',  component: UserComponent},
     { path: 'specialpage',  component: SpecialpageComponent},
     { path: '**',  component: ErrorComponent}
    ];

Look at the content of blockquote. And then you give the name of "HttpModule" at providers:[] in app.module.ts

Thanks.

查看更多
登录 后发表回答