Кутовий маршрутизатор 2.0 не працює над перезавантаженням браузера


190

Я використовую версію Angular 2.0.0-alpha.30. Коли ви переспрямовуєте на інший маршрут, тоді оновіть веб-переглядач, показуючи його Не можна отримати / маршрут.

Чи можете ви допомогти мені зрозуміти, чому сталася ця помилка.


1
Я припускаю , що це stackoverflow.com/questions/16569841
Гюнтер Zöchbauer

Дякую за відповідь, але ця для кутових версій 1.x. Я зіткнувся з проблемою в кутовому 2.0.
Вінц і Тонз

1
Пов'язане питання є загальною проблемою для pushState, а не кутового. Ваше запитання не дає достатньо інформації, щоб знати, чи пов’язана вона.
Günter Zöchbauer

5
Angular 2.0 використовує абсолютно новий маршрутизатор, тому зв'язаний пост зараз не
приносить

Як я вже говорив, якщо це проблема pushState, вона не є кутовою та не може бути виправлена ​​Angular, але її потрібно виправити на сервері.
Günter Zöchbauer

Відповіді:


141

Помилка, яку ви бачите, полягає в тому, що ви запитуєте http: // localhost / route, який не існує. За словами Саймона .

Під час використання маршрутизації html5 вам потрібно зіставити всі маршрути у вашому додатку (зараз 404) до index.html на стороні вашого сервера. Ось кілька варіантів для вас:

  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>
    

1
Оскільки для маршрутизації html5 потрібна підтримка на стороні сервера, це працює чудово. Дякую
Прабхат

Чи можу я використовувати nginx як проксі pub serve? Таким чином, мені не потрібно pub buildбагато під час розвитку. Я намагався, але proxy_passне дуже добре працює error_page.
Франклін Ю

@FranklinYu Я цього раніше не робив. Ви вирішуєте це?
Quy Tang

1
Використання nginx. , error_page 404 /index.html у розташуванні програми працював на мене. Дякую.
Річард К. Кемпіон

2
Tomcat - конфігурація web.xml <error-page> <error-code> 404 </error-code> <location> /index.html </location> </error-page>
A Kunin

65

Відмова від відповідальності: це виправлення працює з Alpha44

У мене була та сама проблема, і я вирішив її, застосувавши HashLocationStrategy, вказаний у перегляді API Angular.io.

https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class.html

Почніть з імпорту необхідних директив

import {provide} from 'angular2/angular2';
import {
  ROUTER_PROVIDERS,
  LocationStrategy,
  HashLocationStrategy
} from 'angular2/router';

І нарешті, завантажте все разом так

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy})
]);

Ваш маршрут буде відображатися як http: // localhost / # / route, і коли ви оновитесь, він перезавантажиться в потрібному місці.

Сподіваюся, що це допомагає!


1
цей код буде добре працювати, але є деяка проблема в цій техніці, використовуючи це #, автоматично додається в URL. чи є яке-небудь рішення для видалення # з URL за допомогою цього?
Pardeep Jain

Погодився, я спробував реалізувати "PathLocationStrategy", вказаний тут , але не зміг його працювати. URL-адреса без цього #була б оптимальною.
SimonHawesome

Так, я теж спробував те ж саме, PathLocationStrategyале це не працює для мене. або я використав неправильний метод, або я не знаю, як використовувати PathLocationStrategy.
Pardeep Jain

1
Це не працює для мене в RC1. Імпортувати LocationStrategy, HashLocationStrategy з "@ angular / router" не вдалося.
infojolt

1
Вибачте, що повернулися до цих питань через більше 1 року :) Але чи допоможе HashLocationStrategy залишитися на тому ж маршруті маршрутизатора? У моєму випадку, коли я оновлюю, це переводить мене до localhost / # / < маршрут за замовчуванням >, тобто маршрут за домашньою сторінкою за замовчуванням. Як мені перейти до поточного маршруту, на якому я був спочатку, коли я "Оновлювався"?
rajugaadu

47

Angular за замовчуванням використовує HTML5 pushstate ( PathLocationStrategyв кутовий сленг).
Вам або потрібен сервер, який обробляє всі запити на зразок запиту, index.htmlабо ви переходите на HashLocationStrategy(з # в URL для маршрутів) https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class. html

Дивіться також https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/

Щоб переключитися на HashLocationStrategyвикористання

оновлення для> = RC.5 та 2.0.0 остаточного

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

@NgModule({
  declarations: [AppCmp], 
  bootstrap: [AppCmp],
  imports: [BrowserModule, routes],
  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
]);

або коротше с useHash

imports: [RouterModule.forRoot(ROUTER_CONFIG, {useHash: true}), ...

переконайтеся, що у вас є весь необхідний імпорт

Для нового (RC.3) маршрутизатора

<base href="."> 

може спричинити і 404.

Це вимагає замість цього

<base href="/">

оновлення для> = RC.x

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy})
  // or since RC.2
  {provide: LocationStrategy, useClass: HashLocationStrategy} 
]);

import {provide} from '@angular/core';
import {  
  PlatformLocation,  
  Location,  
  LocationStrategy,  
  HashLocationStrategy,  
  PathLocationStrategy,  
  APP_BASE_HREF}  
from '@angular/common';  

update for> = beta.16 Імпорт змінився

import {BrowserPlatformLocation} from '@angular/platform-browser';

import {provide} from 'angular2/core';
import {
  // PlatformLocation,
  // Location,
  LocationStrategy,
  HashLocationStrategy,
  // PathLocationStrategy,
  APP_BASE_HREF}
from 'angular2/router';
import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';

<бета.16

import {provide} from 'angular2/core';
import {
  HashLocationStrategy
  LocationStrategy,
  ROUTER_PROVIDERS,
} from 'angular2/router';

Дивіться також https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26 беззмістовні зміни


1
Дякую! здається, що надалі перемістилося під angular / core: import {provide} з 'angular2 / core'
StrangeLoop

1
Зауважимо лише, що: update for >= RC.x(RC.2) працює router 3.0.0-alpha.7, але зазначається provideяк застаріле без інформації про те, яка функція його замінила.
Гнучко

Використання{provide: SomeClass, useClass: OtherClass}
Günter Zöchbauer

2
Найсвіжіша відповідь. Для останньої версії кутового 2.4.1 у мене був <base href = "./">. Змінений на <base href = "/"> вирішив проблему, яку я мав. Можливо, хтось буде корисним.
Saiyaff Farouk

28

Я думаю, що помилка, яку ви бачите, полягає в тому, що ви запитуєте http: // localhost / route, який не існує. Вам потрібно переконатися, що ваш сервер буде відповідати всім запитам на вашу головну сторінку index.html.

Оскільки Angular 2 використовує маршрутизацію html5 за замовчуванням, а не використовувати хеші в кінці URL-адреси, оновлення сторінки виглядає як запит на інший ресурс.


7
так як ми це можемо виправити? як ми відображаємо всі запити до основного індексу за замовчуванням? це надійно на сервері?
Айяш

1
Так, ви б робили це на сервері з будь-якою веб-рамкою, яку ви використовуєте. Альтернативою є використання HashLocationStrategy, як описано нижче.
Саймон

Ви будете перезавантажувати кутовий SPA у кожному немає маршруту. Це як слід поводитися?
Гері

Він завантажується лише в тому випадку, якщо користувач натискає кнопку оновлення в браузері, а не коли користувач міняє маршрути через інтерфейс користувача. Насправді ніяк не можна перезавантажити, коли користувач оновлюється.
Уоллес Ховері

19

Це звичайна ситуація у всіх версіях маршрутизатора, якщо ви використовуєте стратегію розташування HTML за замовчуванням.

Що відбувається, що URL в рядку браузера є нормальним повним HTML URL, як, наприклад: http://localhost/route.

Отже, коли ми натискаємо Enter на панелі браузера, на сервер надсилається фактичний запит HTTP, щоб отримати файл з ім’ям route.

У сервера немає такого файлу, і ніщо на зразок експресу не налаштоване на сервері для обробки запиту та надання відповіді, тому повернення сервера 404 Not Found, оскільки він не міг знайти routeфайл.

Ми хотіли б, щоб сервер повернув index.htmlфайл, що містить програму на одній сторінці. Тоді маршрутизатор повинен запустити і обробити /routeURL-адресу та відобразити на ньому компонент, відображений.

Отже, щоб вирішити проблему, нам потрібно налаштувати сервер для повернення index.html(припускаючи, що це ім'я файлу вашої програми на одній сторінці) у випадку, якщо запит не вдасться обробити, на відміну від 404 Not Found.

Спосіб цього буде залежати від використовуваної технології сервера. Якщо на його Java, наприклад, вам може знадобитися написати сервлет, в Rails це буде інше і т.д.

Щоб навести конкретний приклад, якщо, наприклад, ви використовуєте NodeJs, вам доведеться написати таке програмне забезпечення:

function sendSpaFileIfUnmatched(req,res) {
    res.sendFile("index.html", { root: '.' });
}

А потім зареєструйте його в самому кінці ланцюжка програмного забезпечення:

app.use(sendSpaFileIfUnmatched);

Це буде слугувати index.htmlзамість повернення 404, маршрутизатор запуститься, і все буде працювати, як очікувалося.


Це було саме моє питання. Якщо ви використовуєте NGINX, ця відповідь допомагає вирішити: stackoverflow.com/questions/7027636/…
Натан

Чи є підручник, як це зробити для Java? Дякую.
000000000000000000000

13

Переконайтеся, що це розміщено в головному елементі вашого index.html:

<base href="https://stackoverflow.com/">

Приклад в Angular2 Routing & Навігація документації використовує наступний код в голові замість (вони пояснюють , чому в живому прикладі нотою документації):

<script>document.write('<base href="' + document.location + '" />');</script>

Під час оновлення сторінки це буде динамічно встановлювати базовий href для вашого поточного документа. Я міг бачити, що це спричиняє певну плутанину у людей, які скумують документацію та намагаються повторити планкер.


Дякуємо, що поділилися цим. Будемо просто зрозумілі, він працював для мене лише тоді, коли я клав <base href = "/"> безпосередньо після завантаження всіх css в <head> і перед завантаженням будь-яких файлів Js. Я сподіваюся, що це допоможе комусь
wmehanna

у мене <base href = "./"> у index.html потім видалено '.' від href, і це спрацювало ..
Саураб

10

Якщо ви хочете мати можливість вводити URL-адреси у веб-переглядачі, не налаштовуючи свій AppServer для обробки всіх запитів на index.html, ви повинні використовувати HashLocationStrategy .

Найпростіший спосіб налаштування - це використання:

RouterModule.forRoot(routes, { useHash: true })

Замість:

RouterModule.forRoot(routes)

За допомогою HashLocationStrategy ваші URL-адреси будуть такі:

http://server:port/#/path

Дякую! це допомагає, але я не хочу #з URL, чи можемо ми її видалити?
Хідайт Рахман

7

У мене була така ж проблема з використанням webpack-dev-сервера. Мені довелося додати параметр devServer до свого веб-пакету.

Рішення:

// in webpack
devServer: {
    historyApiFallback: true,
    stats: 'minimal'
}

Вид вуду магії: p Детальніше дивіться на веб-сайті: webpack.github.io/docs/…
Jissay

7

Якщо ви використовуєте Apache або Nginx в якості сервера, ви повинні створити .htaccess(якщо раніше не створено) і "Увімкнути" RewriteEngine

RewriteEngine On  
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html

Не отримали запитання, цей метод перевірено на сервері Apache та Nginx ( nginx.com )
Ракеш Рой,

1
Це лише для Apache; Формат конфігурації Nginx зовсім інший.
Франклін Ю

5

Мій сервер - Apache, те, що я зробив, щоб виправити 404 під час оновлення або глибокого посилання дуже просто. Просто додайте один рядок у конфігурацію apache vhost:

ErrorDocument 404 /index.html

Так що будь-яка помилка 404 буде переспрямована на index.html, а саме цього потрібна маршрутизація angular2.

Приклад всього файлу vhost:

<VirtualHost *:80>
  ServerName fenz.niwa.local
  DirectoryIndex index.html
  ErrorDocument 404 /index.html

  DocumentRoot "/Users/zhoum/Documents/workspace/fire/fire_service/dist"
  ErrorLog /Users/zhoum/Documents/workspace/fire/fire_service/logs/fenz.error.log
  CustomLog /Users/zhoum/Documents/workspace/fire/fire_service/logs/fenz.access.log combined

  <Directory "/Users/zhoum/Documents/workspace/fire/fire_service/dist">
    AllowOverride All
    Options Indexes FollowSymLinks
    #Order allow,deny
    #Allow from All
    Require all granted
  </Directory>

  Header set Access-Control-Allow-Origin "*"
  Header set Access-Control-Allow-Methods "GET, POST"
  Header set Access-Control-Allow-Credentials "true"
  Header set Access-Control-Allow-Headers "Accept-Encoding"
</VirtualHost>

Незалежно від того, яким сервером ви користуєтесь, я думаю, вся суть полягає у пошуку способів налаштування сервера для переадресації 404 на ваш index.html.


4

Конфігурація сервера не є рішенням для SPA - це те, що я навіть думаю. Ви не хочете знову зарядити кутовий SPA, якщо трапляється неправильний маршрут, чи не так? Тому я не залежу від маршруту на сервері та переспрямування на інший маршрут, але так, я дозволю index.html обробляти всі запити для кутових маршрутів кутового шляху програми.

Спробуйте це замість іншого або неправильного маршруту. Це працює для мене, не впевнений, але здається, що незавершена робота. Натрапив на це сам, коли стикався з проблемою.

@RouteConfig([
  { path: '/**', redirectTo: ['MycmpnameCmp'] }, 
   ...
  }
])

https://github.com/angular/angular/isissue/4055

Однак не забудьте налаштувати папки сервера та право доступу у випадку, якщо у вас є HTML або веб-скрипти, які не є SPA. В іншому випадку ви зіткнетеся з проблемами. Для мене, коли ви стикаєтесь з такою проблемою, як ви, це було поєднанням конфігурації сервера і вище.


4

для швидкого виправлення 5, відредагуйте app.module.ts та додайте {useHash:true}після appRoutes.

@NgModule(
{
  imports:[RouterModule.forRoot(appRoutes,{useHash:true})]
})

3

Кутові програми є ідеальними кандидатами для обслуговування простого статичного HTML-сервера. Для динамічного складання сторінок додатків вам не потрібен сервер на базі сервера, оскільки Angular робить це на стороні клієнта.

Якщо програма використовує маршрутизатор Angular, ви повинні налаштувати сервер для повернення хост-сторінки програми (index.html), коли запитується файл, якого у нього немає.

Програмований додаток повинен підтримувати "глибокі посилання". Глибока посилання - це URL-адреса, яка визначає шлях до компонента всередині додатка. Наприклад, http://www.example.com/heroes/42 - це глибоке посилання на сторінку деталей героя, яка відображає героя з ідентифікатором: 42.

Немає жодних проблем, коли користувач переходить до цієї URL-адреси з боку працюючого клієнта. Кутовий маршрутизатор інтерпретує URL-адресу та маршрути до цієї сторінки та героя.

Але натискання посилання в електронному листі, введення його в адресному рядку веб-переглядача або просто оновлення веб-переглядача, перебуваючи на сторінці детальної інформації про героїв, - усіма цими діями керує сам браузер, поза межами запущеної програми. Браузер робить прямий запит на сервер для цієї URL-адреси, минаючи маршрутизатор.

Статичний сервер звичайно повертає index.html, коли отримує запит на http://www.example.com/ . Але він відхиляє http://www.example.com/heroes/42 і повертає помилку 404 - Not Found, якщо вона не налаштована для повернення index.html замість цього

Якщо ця проблема виникла у виробництві, виконайте наступні кроки

1) Додайте файл Web.Config у папку src вашої кутової програми. Розмістіть в ньому код нижче.

<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="/" />
    </rule>
    </rules>
</rewrite>
</system.webServer>
</configuration>

2) Додайте посилання на нього у angular-cli.json. У angular-cli.json помістіть Web.config в блок активів, як показано нижче.

"assets": [
    "assets",
    "favicon.ico",
    "Web.config"
  ],

3) Тепер ви можете побудувати рішення для виробництва, використовуючи

ng build --prod

Це створить папку dist. Файли всередині папки dist готові до розгортання в будь-якому режимі.


Найкраще рішення, можна знайти деталі з кутового: angular.io/guide/deployment#fallback Під час створення файлу web.config не забудьте додати тег <configuration> </configuration>. Дякую за відповідь, Малатеш.
Палаш Рой

3

Ви можете використовувати це рішення для середньої програми, я використовував ejs як механізм перегляду:

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(function (req, res, next) {
    return res.render('index.html');
});

а також встановити в angular-cli.json

"apps": [
    {
      "root": "src",
      "outDir": "views",

це буде працювати нормально замість

app.get('*', function (req, res, next) {
    res.sendFile('dist/index.html', { root: __dirname });
 });

проблема його створення з викликами db та поверненням index.html


1
Це прекрасно спрацювало в жовтні 2017 року для застосунку стека MEAN.
Mindsect Team

2

Для тих, хто бореться за життя в IIS: використовуйте наступний код PowerShell, щоб виправити цю проблему на основі офіційних документів Angular 2 (що хтось розмістив у цій темі? Http://blog.angular-university.io/angular2-router/ )

Import-WebAdministration
# Grab the 404 handler and update it to redirect to index.html.
$redirect = Get-WebConfiguration -filter "/system.WebServer/httperrors/error[@statusCode='404']" -PSPath IIS:\Sites\LIS 
$redirect.path = "/index.html"
$redirect.responseMode = 1
# shove the updated config back into IIS
Set-WebConfiguration -filter "/system.WebServer/httperrors/error[@statusCode='404']" -PSPath IIS:\Sites\LIS -value $redirect

Це перенаправляє 404 до файлу /index.html відповідно до пропозиції в кутових 2 документах (посилання вище).


2

Ви можете спробувати нижче. Це працює для мене!

main.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

...
export class MainComponent implements OnInit {
    constructor(private router: Router) {
        let path: string = window.location.hash;
        if (path && path.length > 0) {
            this.router.navigate([path.substr(2)]);
        }
    }

    public ngOnInit() { }
}

Ви можете додатково покращити path.substr (2), щоб розділити їх на параметри маршрутизатора. Я використовую кутовий 2.4.9


Це було дуже корисно для обробки оновлень браузера! Для кутового 5 мені довелося трохи змінити його, щоб використовувати window.location.pathname і порівняти це значення з очікуваними шляхами.
Уоллес Хоурі,

2

Я просто додаю .htaccess в корінь.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]
    RewriteRule ^ ./index.html
</IfModule>

тут я просто додаю крапку
.


1

Я хотів зберегти шлях URL-адрес підсторінок у режимі HTML5 без перенаправлення назад до індексу, і жодне з рішень там не підказало мені, як це зробити, тому ось як я це здійснив:

Створіть прості віртуальні каталоги в IIS для всіх своїх маршрутів і вкажіть їх на корінь програми.

Загорніть ваш system.webServer у свій Web.config.xml за допомогою цього тегу розташування, інакше ви отримаєте від нього повторювані помилки, завантажуючи Web.config вдруге з віртуальним каталогом:

<configuration>
    <location path="." inheritInChildApplications="false">
    <system.webServer>
        <defaultDocument enabled="true">
            <files>
                <add value="index.html" />
            </files>
        </defaultDocument>
    </system.webServer>
  </location>
</configuration>

1

Я перевірив у куті 2 насінини, як це працює.

Ви можете використовувати express-history-api-backback для автоматичного перенаправлення під час перезавантаження сторінки.

Я думаю, що це найелегантніший спосіб вирішити цю проблему ІМО.


1

Якщо ви хочете використовувати PathLocationStrategy:

  • Конфігурація Wildfly:
    • Створіть файл undertow-handlers.conf для розміщення у WEB-INF
    • Вміст: (виключайте кінцеві точки відпочинку!)
      • regex ['(. / review / ? . ? $)'], а не regex ['(. / endpoints. )'] -> переписати ['/ index.html']
      • regex ['(. / розгортання / ? . ? $)'], а не regex ['(. / endpoints. )'] -> переписати ['/ index.html']

Програма на одній сторінці з Java EE / Wildfly: конфігурація на стороні сервера


1

2017-липень-11: Оскільки це пов’язано з питанням, що має цю проблему, але використовуючи Angular 2 з Electron, я додам тут своє рішення.

Все, що мені потрібно було зробити, - це видалити <base href="./">з мого index.html, і Electron знову почав успішно перезавантажувати сторінку.


1

Додати імпорт:

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

І в провайдера NgModule додайте:

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

У головному index.html Файлі програми змінити базовий href на ./index.htmlз/

Додаток при розгортанні на будь-якому сервері надасть справжній URL для сторінки, доступ до якого можна отримати з будь-якого зовнішнього додатка.


1

Просто додавання .htaccess у корені вирішено 404 під час оновлення сторінки в кутовому 4 apache2.

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

1

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

Використовуючи кутову маршрутизацію на 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) Перезаписати клапан URL-адреси Tomcat: Перепишіть 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]

0

Це не правильна відповідь, але при повторному оновленні ви можете перенаправити всі мертві дзвінки на домашню сторінку, пожертвувавши 404 сторінкою, це тимчасовий хак, просто повторіть наступний файл у файлі 404.html

<!doctype html>
<html>
    <head>
        <script type="text/javascript">
            window.location.href = "http://" + document.location.host;
        </script>
    </head>
</html>

0

Найкраще рішення для вирішення "браузера, який не працює на перезавантаження-браузера", - це те, що ми повинні використовувати спа-падіння назад. Якщо ви використовуєте програму angular2 з ядром asp.net, тоді нам потрібно визначити це на сторінці "StartUp.cs". під маршрутами MVC. Я додаю код.

 app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
            routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
        });

0

Відповідь досить хитра. Якщо ви використовуєте звичайний старий сервер Apache (або IIS), ви отримаєте проблему, оскільки кутові сторінки не існують справжніми. Вони "обчислюються" з кутового маршруту.

Існує кілька способів виправити проблему. Перший - використовувати HashLocationStrategy, запропонований Angular. Але в URL-адресі додається різкий знак. В основному це стосується сумісності з Angular 1 (я припускаю). Справа в тому, що частина після того, як різка не є частиною URL-адреси (тоді сервер вирішує частину перед знаком "#"). Це може бути ідеально.

Тут розширений метод (заснований на хитрість 404). Я припускаю, що у вас є "розподілена" версія вашої кутової програми ( ng build --prodякщо ви використовуєте Angular-CLI), і ви отримуєте доступ до сторінок безпосередньо з вашим сервером, і PHP увімкнено.

Якщо ваш веб-сайт базується на сторінках (наприклад, Wordpress) і у вас є лише одна папка, присвячена Angular (названа "dist" у моєму прикладі), ви можете зробити щось дивне, але, зрештою, просте. Я припускаю, що ви зберегли свої кутові сторінки в "/ dist" (відповідно до <BASE HREF="/dist/">). Тепер використовуйте перенаправлення 404 та допомогу PHP.

У конфігурації Apache (або у .htaccessфайлі каталогу вашого кутового додатка) ви повинні додатиErrorDocument 404 /404.php

404.php почнеться з наступного коду:

<?php
$angular='/dist/';
if( substr($_SERVER['REQUEST_URI'], 0, strlen($angular)) == $angular ){
    $index = $_SERVER['DOCUMENT_ROOT'] . $angular . "index.html";
    http_response_code(200);
    include $index;
    die;
}

// NOT ANGULAR...
echo "<h1>Not found.</h1>"

де $angularзначення, збережене в HREF вашого кута index.html.

Принцип досить простий, якщо Apache не знайде сторінку, перенаправлення 404 робиться до сценарію PHP. Ми просто перевіряємо, чи сторінка знаходиться в каталозі кутових додатків. Якщо це так, ми просто завантажуємо index.html безпосередньо (без перенаправлення): це необхідно, щоб URL-адреса залишалася незмінною. Ми також змінюємо HTTP-код з 404 на 200 (просто краще для сканерів).

Що робити, якщо сторінки не існує у кутовій програмі? Добре, ми використовуємо кутовий маршрутизатор "catch all" (див. Документацію кутового маршрутизатора).

Цей метод працює з вбудованою програмою Angular всередині базового веб-сайту (я думаю, це буде так у майбутньому).

ПРИМІТКИ:

  • Спроба зробити те ж саме mod_redirect(переписавши URL-адреси) - це зовсім не вдале рішення, оскільки файли (як активи) повинні бути дійсно завантажені, то це набагато ризикованіше, ніж просто використовувати рішення "не знайдено".
  • Просто перенаправлення за допомогою ErrorDocument 404 /dist/index.htmlробіт, але Apache все ще відповідає кодом помилки 404 (що погано для сканерів).

0

Це не постійне виправлення проблеми, але більше схоже на вирішення проблеми або зламання

У мене була ця сама проблема при розгортанні моєї програми Angular на gh-сторінках. Спочатку мене привітали 404 повідомлення, коли оновлювали мої сторінки на gh-сторінках.

Тоді, як зазначив @gunter, я почав використовувати, HashLocationStrategyщо було надано Angular 2.

Але це прийшло з його власним набором проблем, #в URL-адресі це було дуже погано, що URL-адресу виглядають дивно, як це https://rahulrsingh09.github.io/AngularConcepts/#/faq.

Я почав досліджувати цю проблему і натрапив на блог. Я спробував дати йому постріл, і це спрацювало.

Ось що я зробив, як згадувалося в тому блозі.

Для початку потрібно буде додати файл 404.html до репо-файлу gh-сторінок, який містить порожній HTML-документ всередині нього - але ваш документ повинен містити більше 512 байт (пояснено нижче). Далі покладіть наступну розмітку у головному елементі сторінки 404.html:

<script>
  sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/REPO_NAME_HERE'"></meta>

Цей код встановлює спробу вхідної URL-адреси на змінну на стандартному об’єкт sessionStorage та негайно перенаправляє на сторінку index.html вашого проекту за допомогою тегу метаоновлення. Якщо ви робите сайт організації Github, не вводьте ім'я репо в текст замінювача атрибутів вмісту, просто зробіть це: content = "0; URL = '/'"

Для того, щоб зафіксувати та відновити URL-адресу, до якої користувач спочатку переходив, вам потрібно буде додати наступний тег сценарію до заголовка сторінки index.html, перш ніж будь-який інший JavaScript діятиме в поточному стані сторінки:

<script>
  (function(){
    var redirect = sessionStorage.redirect;
    delete sessionStorage.redirect;
    if (redirect && redirect != location.href) {
      history.replaceState(null, null, redirect);
    }
  })();
</script>

Цей біт JavaScript отримує URL-адресу, яку ми кешували у sessionStorage на сторінці 404.html, і замінює поточний запис історії на неї.

Довідковий backalleycoder Завдяки @Daniel за цей спосіб вирішення.

Тепер зазначена вище URL-адреса змінюється на https://rahulrsingh09.github.io/AngularConcepts/faq


0

Я виправив це (використовуючи Java / Spring backkend), додавши обробник, який відповідає всьому, визначеному в моїх кутових маршрутах, який надсилає назад index.html замість 404. Це потім ефективно (повторно) завантажує додаток і завантажує правильну сторінку. У мене також є обробник 404 для всього, що цим не зачепить.

@Controller         ////don't use RestController or it will just send back the string "index.html"
public class Redirect {

    private static final Logger logger = LoggerFactory.getLogger(Redirect.class);

    @RequestMapping(value = {"comma", "sep", "list", "of", "routes"})
    public String redirectToIndex(HttpServletRequest request) {
        logger.warn("Redirect api called for URL {}. Sending index.html back instead. This will happen on a page refresh or reload when the page is on an Angular route", request.getRequestURL());
        return "/index.html";
    }
}

0

Якщо ви використовуєте Apache або Nginx в якості сервера, вам потрібно створити .htaccess

<IfModule mime_module>
      AddHandler application/x-httpd-ea-php72 .php .php7 .phtml
    </IfModule>
    # php -- END cPanel-generated handler, do not edit

    <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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.