【问题标题】:Angular RouterModule not woking in productionAngular RouterModule 在生产中不起作用
【发布时间】:2019-03-30 11:34:15
【问题描述】:

我的应用无法在生产环境中运行。

我的应用使用来自@auth0/angular-jwt 的angular-jwt

如果用户有一个有效的令牌,他将被转发到 MainScreenComponent,在其他地方他将被重定向到登录页面。

import { AuthGuard } from './services/Authentication/auth-guard.service';
import { AuthGuardLogin } from './services/Authentication/auth-guard-login.service';
import { AuthService } from './services/Authentication/auth.service';
import { BrowserModule , HAMMER_GESTURE_CONFIG} from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';

import { RouterModule } from '@angular/router';
import { LoginComponent } from './components/login/login.component';
import { NotFoundComponent } from './components/not-found/not-found.component';
import { NoAccessComponent } from './components/no-access/no-access.component';
import { AppComponent } from './app.component';
import { environment } from '../environments/environment';
import { ServiceWorkerModule } from '@angular/service-worker';
import { MainScreenComponent } from './components/main-screen/main-screen.component';
import { JwtModule } from '@auth0/angular-jwt';

export function tokenGetter() {
  return localStorage.getItem('token');
}

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    NotFoundComponent,
    NoAccessComponent,
    MainScreenComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
    RouterModule.forRoot([
       { path: '', component: MainScreenComponent , canActivate: [AuthGuard]},
       { path: 'login', component: LoginComponent,  canActivate: [AuthGuardLogin] },
       { path: '**', component: NotFoundComponent }
     ]),
     JwtModule.forRoot({
      config: {
        tokenGetter: tokenGetter,
        whitelistedDomains: environment.whiteListDomains,
      }
    })
  ],
  providers: [
  AuthService,
  AuthGuard,
  AuthGuardLogin,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

如果我使用 ng serve 一切正常, 但是在 ng build --prod 之后,如果我的初始 URL 是 https://my-site:4300/login,我会得到 404。 在这种情况下,RouterModule 设置将被忽略。

如果我输入 https://my-site:4300,我将被重定向到 https://my-site:4300/login 并显示登录页面。

有什么想法吗?

==========================

2018 年 10 月 31 日更新:

这里是 AuthGuardLogin:

import { AuthService } from './auth.service';
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthGuardLogin implements CanActivate {

  constructor( private router: Router, private authService: AuthService) { }

  canActivate() {
    if (this.authService.isLoggedIn()  === false) {
      return true; }

    this.router.navigate(['/']);
    return false;
  }
}

我现在所做的是将网站托管在 Kestrel 服务器中。 现在它完美无缺。为什么?我不知道:-)!

顺便说一下,Kestrel 服务器托管在 Windows 服务中。所以我可以使用我们的软件包进行部署,并通过常规设置进行安装。

最好的问候,非常感谢你!!!

【问题讨论】:

  • 你在 index.html 页面上使用href="/" 吗?
  • 是的。
  • environment.prod.ts 是否配置正确?你能比较一下environment.prod.tsenvironment.dev.tsenvironment.ts 吗?也许环境文件上的一些变量正在造成问题
  • 嗨。除了生产属性之外,两者完全相同。
  • 让我们看看 git github.com/angular/angular-cli/issues/8515 上的这个 Angular cli 问题,也许你正在用 ServiceWorker 和 base-href 进行类似的实验

标签: angular routing


【解决方案1】:

尝试添加文件src/web.config,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Angular Routes" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="./index.html" />
        </rule>
      </rules>
    </rewrite>
    <staticContent>
      <remove fileExtension=".woff" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".woff2" mimeType="font/x-woff" />
      <remove fileExtension=".otf" />
      <mimeMap fileExtension=".otf" mimeType="font/otf" />
    </staticContent>
  </system.webServer>
</configuration>

它按我的预期工作。我还添加了{ provide: LocationStrategy, useClass: PathLocationStrategy }app.module.ts,以及&lt;base href="/"&gt;index.html,但不知道它是否相关。

【讨论】:

    【解决方案2】:

    您可能需要配置服务器以将不匹配的 URL 重写为 index.html。

    如果您使用的是 IIS,

    1. 在站点下选择网站,
    2. 在 IIS 部分下,双击错误页面
    3. 从列表中选择 404 状态码并以编辑模式打开
    4. 选择单选按钮“在此站点上执行 URL”并在 URL 文本框下写“/”(不带双引号)

    您需要将您的生产网络服务器配置为在检测到 404 时始终使用 index.html 进行响应 - 这样,Angular 将始终加载并且其路由服务将处理客户端的导航。 否则你将不得不使用哈希定位策略。

    编辑: 其他服务器的配置:

    1. 使用实时服务器:https://www.npmjs.com/package/live-server

      $live-server --entry-file=index.html

    2. 使用 nginx:http://nginx.org/en/docs/beginners_guide.html

      error_page 404 /index.html

    3. Tomcat - web.xml 的配置。

      <error-page> <error-code>404</error-code> <location>/index.html</location> </error-page>

    【讨论】:

    • 谢谢!好主意!但我不会在 IIS 下托管它,因为通过常规安装程序将它部署在目标机器上变得更加困难。大多数 Windows 机器上默认不安装 IIS。
    • 正确。但是,您可以在部署此应用程序的任何服务器(如(Apache、Unix))上设置此配置。您在这里遇到的问题是由于单页应用程序框架的性质,例如 Angular。
    • 我已经用其他服务器配置选项更新了我的答案。希望对您有所帮助。
    • 是的,这取决于您运行的服务器类型。我使用 IIS,解决此问题的方法是在 web.config 文件中添加新规则。
    【解决方案3】:

    当刷新错误并且无法识别页面时,我在生产环境中遇到了类似的问题。

    我使用以下方法修复它:imports: [RouterModule.forRoot(routes, { 使用哈希:真 })],

    我建议使用此解决方案,因为您说当您输入默认 url 时它可以工作并在登录时重定向,但是当您输入 /login 时它没有。

    使用useHash是因为angular是一个spa,需要先加载主index.html。在 localhost 和 webpack 中它可以正常工作,但是当您通过服务器为您的应用程序提供服务时,您需要在刷新时通过 index.html 以及在不使用角度路由器时直接点击 url。

    您的网址会变得有点难看,因为将在每个网址之前添加一个#。例如 domain/login 将变为 domain/#/login

    希望对你有帮助

    【讨论】:

    • 感谢您的提示。如果我现在第一次使用登录路由加载 url,我也会收到错误消息。但如果它被缓存了,它现在可以工作了。
    猜你喜欢
    • 2018-07-23
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 2015-02-06
    • 2018-03-13
    • 2020-11-26
    • 2014-01-30
    • 2017-01-02
    相关资源
    最近更新 更多