Обновление результатов страницы в 404 error- Угловое 6

Я создаю приложение с помощью Angular6 и сталкиваюсь с проблемами в маршрутизации. Все маршруты работают, когда я нажимаю на конкретную вкладку, но всякий раз, когда я обновляю текущую страницу, она бросает ошибку 404. Я видел много сообщений об этой проблеме о переполнении стека, но не смог преодолеть эту проблему.

Ниже мой app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {AppComponent} from './app.component';
import {FetchApiComponent} from './fetch-api/fetch-api.component';
import {FormsModule} from '@angular/forms';
import {HttpClientModule} from '@angular/common/http';
import {UserServiceLatest} from './fetch-latest/app.service';
import {UserServiceTop} from './fetch-top/app.service';
import {YoutubePlayerModule} from 'ngx-youtube-player';
import {SidebarComponent} from './sidebar/sidebar.component';
import {FetchLatestComponent} from './fetch-latest/fetch-latest.component';
import { FetchTopComponent } from './fetch-top/fetch-top.component'
import {UserService} from './fetch-api/app.service';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import { AngularFireModule } from 'angularfire2';
import * as firebase from 'firebase';
import { firebaseConfig } from './../environments/firebase.config';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import {PushService} from './push.service';

const appRoutes: Routes = [
  {
    path: '',

  component: FetchApiComponent
  }, 
{
    path: '/latest',

    component: FetchLatestComponent
  },
{
    path: '/top',

    component: FetchTopComponent
  },
{
path :'*',
component: FetchApiComponent 
}

];

firebase.initializeApp(firebaseConfig);

@NgModule({
  declarations: [
    AppComponent,
    FetchApiComponent,SidebarComponent, FetchLatestComponent, FetchTopComponent
  ],
  imports: [
    RouterModule.forRoot(appRoutes),
    BrowserModule, YoutubePlayerModule,
    FormsModule,
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFireDatabaseModule,environment.production ?ServiceWorkerModule.register('firebase-messaging-sw.js'):[],ServiceWorkerModule.register('/firebase-messaging-sw.js', { enabled: environment.production }),
    HttpClientModule,environment.production ? ServiceWorkerModule.register('ngsw-worker.js') : [], ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
  ],
  providers: [UserService,UserServiceTop,UserServiceLatest,PushService],

  bootstrap: [AppComponent]
})
export class AppModule {}

Можете ли вы указать мне в правильном направлении?

Ответ 1

Вы увидите в своем примере url, что, как только вы получите ошибку 404, вы не сможете заставить ее работать, но если вы включите хеш до того, как угловой конкретный URL-адрес, как /#latest он будет работать.

Почему прекращается работа при освежении? ваш веб-сервер перехватывает запрос GET из вашего браузера и пытается перейти непосредственно в каталог /latest, которого не существует. Он не знает, что ему нужно перейти в /bosv2, найти угловое приложение, а затем добавить маленький бит конца к вашему пути, который является не-реальным каталогом, а маршрутизация для углового. В вашем локальном режиме это будет работать, когда вы выполняете ng-службу, для этого готов веб-сервер webpack, но не для хоста, на котором вы размещаете приложение.

По умолчанию угловая использует навигацию по стилю HTML5, но с текущими настройками веб-сервера вам понадобится старый стиль angularjs (с хешем #).

Отсюда у вас есть два решения:

  1. Изменение конфигурации вашего веб-сервера
  2. Скажите Angular, чтобы использовать HashLocationStrategy (совершенно правильное решение), вы можете пойти в старую школу с помощью HashLocationStrategy, предоставив useHash: true в объекте в качестве второго аргумента RouterModule.forRoot в AppModule.

    @NgModule ({import: [... RouterModule.forRoot (маршруты, {useHash: true})//.../#/latest/],...

Я бы сказал, что в стиле хэша есть несколько недостатков, которые могут быть неактуальны в вашем сценарии:

  1. Он не создает чистые и удобные для SEO URL-адреса, которые пользователям легче понять и запомнить.
  2. Вы не можете воспользоваться рендерингом на стороне сервера.

Надеюсь, вы найдете этот ответ полезным :)

Ответ 2

С.htaccess вы также можете попробовать следующим образом:

<IfModule mod_rewrite.c>
    RewriteEngine on

    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]

    # Rewrite everything else to index.html
    # to allow html5 state links
    RewriteRule ^ index.html [L]
</IfModule>

Ответ 3

Чтобы избежать использования хэшированных маршрутов, вы должны правильно отредактировать конфигурацию вашего веб-сервера, что является лучшим решением. Вам просто нужно настроить его так, чтобы он откатывался на index.html, то есть Angular bootstrap. Хотя для этого нет универсальной конфигурации, вот некоторые из них:

Apache

Добавить правило перезаписи в файл .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 does not exist, use index.html
RewriteRule ^ /index.html

Nginx

Используйте try_files в своем блоке местоположения

try_files $uri $uri/ /index.html;

IIS

IISДобавить правило перезаписи в web.config

<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>
</system.webServer>

Источник: https://angular.io/guide/deployment#server-configuration

Ответ 4

В app.module.ts

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

После импорта добавьте следующую строку поставщикам.

{provide: LocationStrategy, useClass: HashLocationStrategy}

ex:

providers: [AuthService, 
            AuthGuard, 
            FlxUiDataTable,
            {provide: LocationStrategy, useClass: HashLocationStrategy}]

Это решит вашу проблему. Прочитайте документацию здесь.

Ответ 5

Я думаю, что вы получаете 404, потому что вы запрашиваете http://localhost/route, который не существует на сервере Tomcat. Поскольку Angular 2 использует маршрутизацию html 5 по умолчанию, а не использует хэши в конце URL-адреса, обновление страницы выглядит как запрос другого ресурса.

При использовании angular маршрутизации на tomcat вы должны убедиться, что ваш сервер будет сопоставлять все маршруты в вашем приложении с вашим основным index.html при обновлении страницы. Есть несколько способов решить эту проблему. В зависимости от того, что вам подходит, вы можете пойти на это.

1) Поместите следующий код в web.xml вашей папки развертывания:

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

2) Вы также можете попробовать использовать HashLocationStrategy С# в URL для маршрутов:

Попробуйте использовать:

RouterModule.forRoot (маршруты, {useHash: true})

Вместо:

RouterModule.forRoot (маршруты)

С HashLocationStrategy ваши URL будут выглядеть так:

http://localhost/#/route

3) Tomcat URL Rewrite Valve: переписать URL, используя конфигурацию уровня сервера, чтобы перенаправить на index.html, если ресурс не найден.

3.1) Внутри папки META-INF создайте файл context.xml и скопируйте в него приведенный ниже контекст.

<? xml version='1.0' encoding='utf-8'?>
<Context>
  <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>

3.2) Внутри WEB-INF создайте файл rewrite.config (этот файл содержит правило перезаписи URL и используется tomcat для перезаписи URL). Внутри rewrite.config скопируйте содержимое ниже:

RewriteCond% {SERVLET_PATH}! -f

RewriteRule ^/(. *) $/Index.html [L]

Ответ 6

В моем случае я сделал следующее

Метод 1:

в вашем app.module.ts импортируемой ниже вещи

import { HashLocationStrategy, LocationStrategy } from '@angular/common';
@NgModule({
  declarations: [...],
  imports: [...],
  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
  bootstrap: [AppComponent]
})

и строить с помощью

ng build --base-href/[PROJECT_NAME]/

Способ 2:

для nginx

nano/etc/nginx/sites-available/default

добавить следующую строку в блоке местоположения

location /[PROJECT_NAME] {
  try_files $uri $uri/ /[PROJECT_NAME]/index.html;
}

sudo service nginx restart

и строить с

ng build --base-href/[PROJECT_NAME]/