部署到Http Server时,Angular 2路由不起作用

时间:2017-04-21 06:03:37

标签: angular npm angular2-routing angular-cli angular2-template

我将开发一个简单的Angular 2应用程序。我使用Angular CLI创建了一个带路由的项目,并使用“生成组件”向应用程序添加了几个组件。命令。然后我在 app-routing.module.ts 中指定了路由,如下所示。

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 如下。

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

我没有为其他组件添加任何修改。 然后我使用' ng serve'部署了应用程序。命令和应用程序与链接正常工作。 例如:http://localhost:4200/about

enter image description here

但是当我在http-server中部署项目时,链接无法按预期工作。我使用' http-server ./dist'部署了应用程序。命令和应用程序部署正常,但链接不起作用。当我转到' http://localhost:4200/about'时,会出现404错误。

enter image description here

我做错了吗?为什么' ng-serve'工作和' http-server'不起作用?

任何帮助将不胜感激。提前致谢。

我已将我的项目上传到github

18 个答案:

答案 0 :(得分:23)

通过实施HashLocationStrategy向所有路由添加#来解决此问题。您可以通过添加HashLocationStrategy to AppModule providers来实现此目标。

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

并添加相应的导入

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

这将解决您的问题。

如果您不想使用HashLocationStrategy,则可以使用PahtLocationStrategy,因此您的Angular应用不会在网址中显示哈希值。 有关它的更多详细信息,请查看官方链接:https://angular.io/api/common/PathLocationStrategy

答案 1 :(得分:11)

这是因为http-server不支持lite-server或web pack-dev服务器等 fallback 。这就是为什么它显示 404 not found 。 解决此问题有2个解决方案2解决方案:

  1. 您可以使用上面提到的 HashLocationStrategy
  2. 如果要将其部署到Apache或IIS服务器,那么您只需按照提及here添加配置即可!
  3. 注意:对于开发,您可以使用lite-server。

    希望这会对你有所帮助。

答案 2 :(得分:6)

会发生这种情况,因为它会找到一个关于的页面,因此根本就没有内容404.可能的选项:

  1. 如果您想使用http-server,请使用代理将所有内容重定向到http://localhost:your-port

    选项: -P--proxy代理所有无法在本地解析到给定网址的请求。例如:-P http://someurl.com

  2. 根本不使用快递。使用express& amp;创建您自己的http服务器将所有内容重定向到index.html

    假设public是您保存所有已转换内容的文件夹。

    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 :(得分:4)

我已通过在AppModule提供程序中添加此问题解决了该问题:

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

并导入

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

然后我创建了.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

在URL中没有#的情况下,一切都很好:)

答案 4 :(得分:2)

它将以这种方式解决:

案例1:对于小于Angular 5.1的版本

1)使用 HashLocationStrategy ,如下所述: 在 AppModule 中执行以下操作。

1.1)2

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

案例2:对于等于或高于Angular 5.1的版本

2.1)Angular引入了此属性 onSameUrlNavigation ,以克服服务器上的刷新问题。

2.2)将 onSameUrlNavigation 添加到导入数组中的providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]

a)在应用程序主路由模块中,i,e app.routing.module.ts / app.routing.ts添加属性

见下文:

RouterModule.forRoot

希望对某人有所帮助。

答案 5 :(得分:1)

对于Apache服务器:

生产服务器中的

在项目根目录中添加或创建“.htaccess”文件,向.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

答案 6 :(得分:1)

如果您像我一样,根本不想更改任何代码,只需使用以下代码即可

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

答案 7 :(得分:0)

我也遇到了这个问题,找到了不需要HashLocationStrategy解决方案的解决方案。

问题是,类似于tomcat的服务器会在角度应用程序中查找一个不存在于实际应用程序中的文件夹(例如:/ about),作为其单页应用程序。因此,每个请求都需要重定向到index.html。

解决此问题的最简单方法是添加以下java类,并覆盖 addResourceHandlers ()方法,如下所示:

@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;
                }
            });
    }
  }

这将解决所有问题,并且该解决方案在任何地方都不存在。

答案 8 :(得分:0)

我使用了lite-server。

npm i -D  lite-server

然后在我的package.json文件中:

"scripts": {
   "ci:serve:employee-onboarding": "ng build --prod --project=employee-onboarding && lite-server -c lite-server-config.json"
}

运行它:npm run ci:serve:employee-onboarding

我的lite-server-config.json文件看起来像这样

{
  "port": 4201,
  "server": { "baseDir": "dist/apps/employee-onboarding" }
}

答案 9 :(得分:0)

在基本href字符串中添加一个点。

正确

    [Required]
    [Display(Name = "Mobile number")]
    public string PhoneNumber { get; set; }

    [Required]
    [Display(Name = "Email")]
    public string Email{ get; set; }

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

答案 10 :(得分:0)

遇到此特定问题的确切原因是由于您的服务器设置。

因此,在实施应用程序时,您将必须执行某些步骤。 基本步骤之一是标记路径的特定部分,例如:  http://domain-name/main 在服务器设置中,必须使用 main 作为路径段作为标识符,例如,当涉及到 server.js app.js 时IIS和Tomcat部署的节点后端或 webconfig 文件。

标记特定网段的原因是,当服务器收到具有该特定网段的请求时,您会将其重新路由到www或公用文件夹中的应用程序,以启动角路由器。

此过程称为 URL重写。 因此,如果Web服务器或取决于应用程序大小的应用程序服务器不受您的控制,请使用 hashLocationStratergy ,否则使用 pathLocationStartergy 总是很整洁的,因为这会有所帮助涉及历史跟踪以及其他美学和性能方面的好处。

要了解更多信息,请访问以下链接:

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

答案 11 :(得分:0)

您应尝试从应用程序应初始化的位置开始在构建中指定网址:

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

答案 12 :(得分:0)

根据https://angular.io/guide/deployment中的文档(Apache,您也可以寻找nginx)  您需要使用.htaccess文件作为

将服务器指向index.html。
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

答案 13 :(得分:0)

对于Apache服务器

  • 创建文件名.htaccess
  • 编辑该文件并写入index.html而不是index.php
  • 对于那些没有任何代码的人,可以在您的.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

  • 此代码可能不适用于SSL证书-请与您的托管服务提供商联系,或访问https://httpd.apache.org/docs/current/howto/htaccess.html以引用文档。

答案 14 :(得分:-1)

在项目文件夹中创建.htaccess文件然后写

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]

点击此链接: https://angular.io/guide/deployment

答案 15 :(得分:-1)

更改index.html

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

因为我们使用的是Tomcat,所以我们已经提到了这个(。) for routing是基于此(/)所以像http-server

一样

我的意思是正常运行你只看到过的服务 http://localhost:4200/

但是在服务器中运行,你已经将你的构建放入web应用程序中的(dist)

所以它就像

http://localhost:8080/dist/

因此您需要添加<base href="./">

我认为这是你可能解决的问题。

答案 16 :(得分:-1)

您可以在注册RouterModule.forRoot时执行此操作,您可以使用属性{useHash:true}传递第二个对象,如下所示:

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

答案 17 :(得分:-1)

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

查看blockquote的内容。 然后你给出&#34; HttpModule&#34;的名字。在app.module.ts的providers:[]

感谢。