Обновление результатов страницы в 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 (с хешем #).
Отсюда у вас есть два решения:
- Изменение конфигурации вашего веб-сервера
-
Скажите Angular, чтобы использовать HashLocationStrategy (совершенно правильное решение), вы можете пойти в старую школу с помощью HashLocationStrategy, предоставив useHash: true
в объекте в качестве второго аргумента RouterModule.forRoot в AppModule.
@NgModule ({import: [... RouterModule.forRoot (маршруты, {useHash: true})//.../#/latest/],...
Я бы сказал, что в стиле хэша есть несколько недостатков, которые могут быть неактуальны в вашем сценарии:
- Он не создает чистые и удобные для SEO URL-адреса, которые пользователям легче понять и запомнить.
- Вы не можете воспользоваться рендерингом на стороне сервера.
Надеюсь, вы найдете этот ответ полезным :)
Ответ 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]/