ChatGPT解决这个技术问题 Extra ChatGPT

Angular 2 路由在部署到 Http 服务器时不起作用

我将开发一个简单的 Angular 2 应用程序。我使用 Angular CLI 创建了一个带有路由的项目,并使用“ng generate component”命令向应用程序添加了几个组件。然后我在 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

https://i.stack.imgur.com/HaRAb.jpg

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

https://i.stack.imgur.com/FWOme.jpg

我做错什么了吗?为什么“ng-serve”有效而“http-server”无效?

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

我已将我的项目上传到 github

试试 imports: [RouterModule.forRoot(routes, {useHash: true})],。如果它以这种方式工作,您需要在生产服务器上启用 HTML5 pushState。
@GünterZöchbauer,我试过了,但没有运气
是的,不要使用 useHash:true :D。正如我在最初的评论中所说。您必须配置服务器以支持 HTML5 pushState。 useHash:true 只是为了调试问题的原因。
@GünterZöchbauer,感谢您提供有关此事的宝贵信息。我将尝试为此找到解决方案。再次感谢
你找到解决办法了吗。我有同样的问题。

P
Phil Dukhov

这个问题通过实施 HashLocationStrategy 解决,它将 # 添加到您的所有路线。您可以通过将 HashLocationStrategy 添加到 AppModule providers 来实现此目的。

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

并添加相应的导入

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

这将解决您的问题。

如果您不想使用 HashLocationStrategy,您可以使用 PathLocationStrategy,这样您的 Angular 应用程序就不会在 URL 中显示 Hash。


我有同样的问题,我的 app.modules.ts 中也有这个问题。我没有收到任何 404 错误。在应用程序组件 init 方法之后,没有任何内容加载,就好像我的路线不起作用一样。 ng serve 工作正常,但我的本地主机不行。
谢谢!帮助过我。但是在已部署的网站 url 中始终显示主题标签是否可以?唔
@ninjaxlite 如果您不想在 URL 中显示 Hashtag,我更新了我的答案
我觉得这不应该是一件事。修复这个谷歌。改变整个互联网的结构来安抚我。
这个。我已经尝试了各种方法让它在我的 nginx 和 IIS 上运行 - 无济于事。直到我遇到了这个。我们不是都希望 Angular 默认使用 HashLocationStrategy 吗?或者,甚至更远,它甚至不应该是不使用它的选项?
D
Davide

这是因为 http-server 不支持像 lite-server 或 web pack-dev server 这样的回退。这就是为什么它显示 404 未找到。有两种解决方案可以解决此问题:

您可以使用上面提到的 HashLocationStrategy 。如果您将其部署到 Apache 或 IIS 服务器,那么您可以简单地添加此处提到的配置!

注意:对于开发,您可以使用 lite-server。

希望这会帮助你。


M
Maciej Socha

我已经通过在 AppModule Providers 中添加这个解决了这个问题:

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 中,一切都很好 :)


我必须在哪里添加 .htaccess 文件?
@jaykhatri 在您的 Web 服务器上的主目录(Angular 应用程序所在的位置)中。它可能是public_html。
B
Benjamin

会这样解决:

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

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

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

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

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

2.1) Angular 引入了这个属性 onSameUrlNavigation 来克服服务器上的刷新问题。

2.2) 将 onSameUrlNavigation 添加到 imports 数组 中的 RouterModule.forRoot 中。

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

见下文:

@ngModule({

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

    exports: [RouterModule],
 });

希望它可以帮助某人。


T
TT.

它会发生,因为它会找到一个根本不存在的页面,因此是 404。可能的选项:

如果您想使用 http-server,请使用代理,它将所有内容重定向到 http://localhost:your-port。选项:-P 或 --proxy 代理所有无法在本地解析到给定 url 的请求。例如:-P http://someurl.com 根本不要使用 express。使用 express 创建您自己的 http-server 并将所有内容重定向到 index.html 假设 public 是您保存所有转译内容的文件夹。 var express = require('express'); var app = express(); var path = __dirname + '/public';变量端口 = 8080; app.use(express.static(path)); app.get('*', function(req, res) { res.sendFile(path + '/index.html'); }); app.listen(端口);


对不起,我没有让你很好。我真的是 Angular 的新手。我在这里没有做任何复杂的事情。关于您的第一个选项,我尝试托管我的服务器并且我在没有端口的情况下访问了 URL。只有根 URL 有效。无法导航到其他链接。
http-server --port 4200 -P http://someurl.com 在我的情况下引发了一个无限循环
S
Sharpiro

如果你和我一样,不想做任何代码更改,只需使用它来代替:

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


T
Tanvir Sarker

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

u
user2332505

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

问题是,像 tomcat 这样的服务器会查找 Angular 应用程序中不存在的实际文件夹(例如: /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;
                }
            });
    }
  }

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


很高兴知道有这样的解决方案,但我认为最好使用 Angular 提供的机制,例如上面提到的 -> HashLocationStrategy。干杯:)
N
Nick

您应该尝试从应用程序初始化的点开始指定构建中的 url:

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

a
abhay

面临此特定问题的确切原因是您的服务器设置。

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

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

这个过程称为 url 重写。因此,如果取决于应用程序大小的 Web 服务器或应用程序服务器不受您的控制,那么请使用 hashLocationStratergy 否则使用 pathLocationStartergy 总是很整洁,因为它在历史跟踪和其他美学和性能优势方面很有帮助。

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

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


d
dbc

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

S
Smit Patel

对于 Apache 服务器

创建文件名 .htaccess

编辑该文件并编写 index.html 而不是 index.php

对于那些没有任何代码的人,可以在您的 .htaccess 文件中编写以下代码: RewriteEngine On # 如果请求现有资产或目录,请转到它,因为它是 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] # 如果请求的资源不存在,使用 index.html RewriteRule ^ /index.html

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


A
Akrime

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

正确的

<base href="./home">

错误的

<base href="/home">

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


T
Talha Akca

如果您使用href,请将它们更改为routerlink。


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

查看blockquote的内容。然后在 app.module.ts 中的 providers:[] 处给出“HttpModule”的名称

谢谢。


@C.Peterscu 我做了你提到的。但我无法让它工作。我将我的项目上传到 github.com/kinathru/multiple-page-app
a
abahet

您可以在注册 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 {}

我有同样的问题,但解决方案不起作用
我有同样的问题。 ng serve 效果很好,但是当我部署到本地时,localhost/ 不起作用
测试时不要忘记在 URL 中使用哈希,例如:127.0.0.1/#/home
K
Karnan Muthukumar

更改您的 index.html

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

因为我们使用的是 Tomcat 我们已经提到了 this(.) 用于路由是基于 this(/) 所以和 http-server 一样

我的意思是正常运行 ng serve 你只见过 http://localhost:4200/

但是在服务器上运行你已经把你的构建放入(dist)的 webapps

所以它就像

http://localhost:8080/dist/

所以你需要添加 <base href="./">

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


A
Amr Abdalrahman

在项目文件夹中创建 .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


u
user372225

我使用了精简服务器。

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