Angular RouterModule在生产中无法正常运行

时间:2018-10-25 18:58:08

标签: angular routing

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

我的应用使用来自@ 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服务,一切都会按预期进行, 但是在 ng build --prod 之后,如果我的初始URL为 https://my-site:4300/login ,则会收到404。 在这种情况下,RouterModule设置将被忽略。

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

有什么想法吗?

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

更新31.10.2018:

这是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服务中托管的方式。因此,我可以使用我们的软件包进行部署,并通过常规设置进行安装。

最诚挚的问候,非常感谢!

3 个答案:

答案 0 :(得分:5)

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

我通过以下方式修复了该问题:导入:[RouterModule.forRoot(routes,{     useHash:true   })],

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

使用

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

尽管,您的网址会变得有些丑陋,因为将在每个网址之前添加#。例如,域/登录将变为域/#/登录

希望它对您有帮助

答案 1 :(得分:4)

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

如果您使用的是IIS,

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

您需要将生产Web服务器配置为始终在检测到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>

答案 2 :(得分:0)

尝试添加具有以下内容的文件 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,并将 <base href="/"> 添加到 index.html,但不确定它是否相关。