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

введите описание изображения здесь

Но когда я развертываю проект на http-сервере, ссылки работают не так, как ожидалось. Я развернул приложение, используя команду "http-server./dist", и приложение отлично развернуто, но ссылки не работают. Когда я перехожу к http://localhost:4200/about ', он дает ошибку 404.

введите описание изображения здесь

Я делаю что-то неправильно? Почему "ng-serve" работает и "http-server" не работает?

Любая помощь будет оценена по достоинству. Заранее спасибо.

Я загрузил свой проект в github.

Ответ 1

Эта проблема решается путем реализации HashLocationStrategy которая добавляет # ко всем вашим маршрутам. Это достигается путем добавления HashLocationStrategy to AppModule providers.

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

и добавьте соответствующий импорт

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

Это решит вашу проблему.

И если вы не хотите использовать HashLocationStrategy, вы можете использовать PahtLocationStrategy, и ваше приложение Angular не будет отображать Hash в URL. Для получения более подробной информации об этом проверьте официальную ссылку: https://angular.io/api/common/PathLocationStrategy

Ответ 2

Это связано с тем, что http-сервер не поддерживает резервный, такой как сервер lite-server или web pack-dev. Вот почему он показывает 404 не найден. Есть два решения для решения этой проблемы:

  • вы можете использовать HashLocationStrategy, как указано выше.
  • Если вы развертываете его на сервере Apache или IIS, вы можете просто добавить конфигурации, как указано здесь!

Примечание. Для разработки вы можете использовать Lite-сервер.

Надеюсь, это поможет вам.

Ответ 3

Это произойдет, потому что он найдет страницу о, которой нет внутри, поэтому 404. Возможные варианты:

  • Если вы хотите пойти с http-сервером, используйте прокси-сервер, который перенаправит все на http://localhost:your-port.

    Опция: -P или --proxy Проксирует все запросы, которые не могут быть разрешены локально с заданным URL-адресом. например: -P http://someurl.com

  • Не используйте выражение вообще. Создайте свой собственный http-сервер, используя экспресс и перенаправляйте все на index.html

    Предполагая, что публикация - это ваша папка, в которой вы сохраняете все переданные вещи.

    var express = require('express');
    var app = express();
    
    var path = __dirname + '/public';
    var port = 8080;
    
    app.use(express.static(path));
    app.get('*', function(req, res) {
        res.sendFile(path + '/index.html');
    });
    app.listen(port);
    

Ответ 4

Я решил эту проблему, добавив это в провайдеры AppModule:

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 :)

Ответ 5

Он будет решен таким образом:

Case-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 в RouterModule.forRoot в массив импорта.

a) В модуле основной маршрутизации приложения i, e app.routing.module.ts/app.routing.ts добавляет свойство

См. ниже:

@ngModule({

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

    exports: [RouterModule],
 });

Надеюсь, что это поможет кому-то.

Ответ 6

Для сервера 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

Ответ 8

Для сервера Apache

  • Создать имя файла .htaccess
  • Отредактируйте этот файл и напишите index.html вместо index.php
  • Для тех, у кого нет никакого кода, можете написать приведенный ниже код в вашем файле .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

  • Этот код может не работать для SSL-сертификата - обратитесь к вашему хостинг-провайдеру ИЛИ посетите https://httpd.apache.org/docs/current/howto/htaccess.html, чтобы обратиться к документации.

Ответ 9

В соответствии с документацией по адресу https://angular.io/guide/deployment (Apache, вы также можете поискать nginx). Вам нужно указать серверу index.html, используя файл.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

Ответ 10

Вы должны попытаться указать URL-адрес в сборке с момента инициализации приложения:

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

Ответ 11

Точная причина, по которой эта конкретная проблема встречается, связана с настройками вашего сервера.

Поэтому, когда вы реализуете приложение, вы должны предпринять определенные шаги. Одним из важных шагов является выделение определенного сегмента вашего пути, например: http://domain-name/main, где main, являющийся сегментом пути, должен использоваться в качестве идентификатора в настройках вашего сервера, скажем, ваш server.js или app.js когда дело доходит до бэкэнда узла или файла webconfig для развертывания IIS и Tomcat.

Причина пометки определенного сегмента заключается в том, что когда сервер получает какой-либо запрос с этим конкретным сегментом + дополнительный, вы перенаправляете его в свое приложение в www или общедоступной папке для запуска углового маршрутизатора.

Этот процесс известен как перезапись URL. Следовательно, если веб-сервер или сервер приложений, в зависимости от размера приложения, не находятся под вашим контролем, используйте hashLocationStratergy, в противном случае всегда полезно использовать pathLocationStartergy, поскольку это полезно при отслеживании истории и других эстетических преимуществах и производительности.

Чтобы узнать больше об этом вы можете посетить эти ссылки:

Для IIS: https://blog.angularindepth.com/deploy-an-angular-application-to-iis-60a0897742e7

Ответ 13

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

Посмотрите на содержимое blockquote. И затем вы даете имя "HttpModule" в providers:[] в app.module.ts

Спасибо.

Ответ 14

Вы можете сделать это во время регистрации вашего 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 {}

Ответ 15

Измените index.html

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

Поскольку мы используем Tomcat, мы упомянули об этом (.) для маршрутизации основано на этом (/) Так же, как http-server

Я имею в виду, что вы работаете нормально, как только вы видели http://localhost:4200/

но запустив сервер, вы поместили свою сборку в (dist) в webapps

поэтому он приходит как

http://localhost:8080/dist/

поэтому вам нужно добавить <base href="./">

Я думаю, что это проблема, потому что вы можете решить.

Ответ 16

в папке проекта создайте файл .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