Угловой 2.0 маршрутизатор не работает при перезагрузке браузера


Я использую угловой 2.0.0-Альфа.30 версия. При перенаправлении на другой маршрут, а затем обновить браузер, его показ не может получить / маршрут.

можете ли вы помочь мне выяснить, почему эта ошибка произошла.

27 141

27 ответов:

ошибку вы видите потому что вы запрашиваете http://localhost/route, которого не существует. Согласно Симон.

при использовании HTML5 маршрутизации вам нужно сопоставьте все маршруты в вашем приложении(в настоящее время 404) для индексирования.HTML-код на стороне сервера. Вот несколько вариантов для вас:

  1. использование live-server: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-конфигурация сети.XML. От Кунинкомментарий

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

отказ от ответственности: это исправление работает с Alpha44

у меня была такая же проблема и решил ее реализации HashLocationStrategy перечисленные в Angular.io предварительный просмотр API.

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 все это вместе, как так

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

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

надеюсь, что это поможет!

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

см. также https://ngmilk.камни/2015/03/09/в AngularJS-поддержка HTML5-режиме-или-очень-адресов-на-Апач-через-или/

To переключиться на 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';  

обновление ПО >= бета.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';

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

Я думаю, что ошибка, которую вы видите, потому что ваш запрос http://localhost/route, которого не существует. Вам нужно убедиться, что ваш сервер сопоставит все запросы с вашим основным индексом.HTML-страница.

поскольку Angular 2 использует маршрутизацию html5 по умолчанию, а не использует хэши в конце url-адреса, обновление страницы выглядит как запрос на другой ресурс.

это обычная ситуация во всех версиях роутера, Если вы используете стратегию расположения HTML по умолчанию.

что происходит, так это то, что URL-адрес на панели браузера является обычным полным url-адресом HTML, например:http://localhost/route.

поэтому, когда мы нажимаем Enter в строке браузера, есть фактический HTTP-запрос, отправленный на сервер, чтобы получить файл с именем route.

сервер не имеет такого файла, и ни что-то вроде express не настроено на сервере, чтобы обработайте запрос и предоставьте ответ, поэтому сервер return 404 не найден, потому что он не смог найти .

то, что мы хотели бы для сервера, чтобы вернуть index.html файл, содержащий одностраничное приложение. Затем маршрутизатор должен пнуть и обработать /route url и отображение компонента, сопоставленного с ним.

поэтому для устранения проблемы нам нужно настроить сервер для возврата index.html (предполагая, что это имя одной странице приложения файл) в случае если запрос не может быть обработан, в отличие от 404 не найдена.

способ сделать это будет зависеть от используемой технологии на стороне сервера. Если его Java, например, вам, возможно, придется написать сервлет, в Rails он будет другим и т. д.

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

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

и затем зарегистрировать его в самом конце промежуточного цепь:

app.use(sendSpaFileIfUnmatched);

это будет служить index.html вместо того, чтобы вернуть 404, маршрутизатор включится, и все будет работать так, как ожидалось.

убедитесь, что это помещается в главный элемент вашего индекса.html:

<base href="/">

The пример в Angular2 Маршрутизация И Навигация документация использует следующий код в голове вместо этого (они объясняют, почему в живом примере Примечание документации):

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

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

У меня была такая же проблема с использованием webpack-dev-server. Мне пришлось добавить опцию devServer в свой веб-пакет.

устранение:

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

Если вы хотите иметь возможность вводить URL-адреса в браузере без настройки вашего сервера приложений для обработки всех запросов на индексацию.HTML, вы должны использовать HashLocationStrategy.

самый простой способ настроить с помощью:

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

вместо:

RouterModule.forRoot(routes)

С HashLocationStrategy ваши URL-адреса будут похожи:

http://server:port/#/path

мой сервер Apache, что я сделал, чтобы исправить 404, когда обновление или глубокое связывание очень просто. Просто добавить одну строчку в конфиг Апача для виртуального хоста:

ErrorDocument 404 /index.html

Так что любая ошибка 404 будет перенаправлена в индекс.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 на ваш индекс.формат html.

Если вы используете Apache или nginx в качестве сервера, вы должны создать .htaccess (если не создано ранее) и" On " RewriteEngine


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

конфигурация сервера не является решением для СПА-это то, что даже я думаю. Вы не хотите, чтобы перезагрузить угловой СПА снова, если неправильный маршрут приходит, не так ли? Так что я не буду зависеть от маршрута сервера и перенаправлять на другой маршрут, Но да я позволю индексировать.html обрабатывает все запросы на угловые маршруты углового пути приложения.

попробуйте это вместо других или неправильных маршрутов. Это работает для меня, не уверен, но кажется, что работа продолжается. Споткнулся об это сам, когда столкнулся с Ан вопрос.

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

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

однако не забудьте настроить папки сервера и право доступа в случае, если у вас есть HTML или веб-скрипты, которые не являются SPA. Иначе вы столкнетесь с проблемами. Для меня, когда я столкнулся с такой проблемой, как вы, это было сочетание конфигурации сервера и выше.

you can use this solution for mean application

i used ejs as view engine

 // 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');
});

and also set in angular- cli .json
"apps": [
    {
      "root": "src",
      "outDir": "views",

it will work fine instead of 

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

its creating issue with get db calls and returning index.html

для углового 5 быстрого исправления, редактировать приложение.модуль.ТС и добавить {useHash:true} после appRoutes.

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

для тех из нас, кто борется за жизнь в 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-файл в соответствии с предложением в Angular 2 docs (ссылка выше).

вы можете попробовать ниже. Это работает для меня!

main.деталь.ТС

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() { }
}

вы можете улучшить путь.substr (2) для разделения на параметры маршрутизатора. Я использую угловой 2.4.9

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

создайте простые виртуальные каталоги в IIS для всех ваших маршрутов и укажите их в корне приложения.

оберните вашу систему.веб-сервер в вашем интернете.конфиг.xml с этим тегом местоположения, в противном случае вы получите повторяющиеся ошибки от него загрузки веб.конфигурация во второй раз с виртуальным каталог:

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

Я проверил в angular 2 seed, как это работает.

можно использовать express-history-api-fallback для автоматического перенаправления при перезагрузке страницы.

Я думаю, что это самый элегантный способ решить эту проблему ИМО.

Если вы хотите использовать PathLocationStrategy:

  • настройки Wildfly :
    • создать undertow-обработчики.файл conf для размещения в WEB-INF
    • Content : (исключите свои конечные точки rest !)
      • регулярное выражение['(./обзор/?.?$ ) '], а не регулярное выражение['(./конечные точки.)'] - > переписать ['/index.html']
      • регулярное выражение['(./развертывания/?.?$ ) '] а не регулярное выражение.('[/конечные точки.)'] - > переписать ['/index.html']

одностраничное приложение с Java EE/Wildfly: конфигурация на стороне сервера

Это не правильный ответ, но при обновлении вы можете перенаправить все мертвые вызовы на домашнюю страницу, пожертвовав 404 страницей, это временный хак, который просто воспроизводится после 404.html файл

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

лучшее решение решения "маршрутизатор-не-работает-на-перезагрузка-браузер" является то, что мы должны использовать spa-отступить. Если вы используете приложение angular2 с asp.net ядро тогда нам нужно определить его на " StartUp.страница "КС". по пути в MVC. Я прилагаю код.

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

2017-Июль-11: так как это связан из вопроса, имеющего эту проблему, но использующего угловой 2 с электроном, я добавлю свое решение здесь.

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

ответ довольно сложно. Если вы используете простой старый сервер Apache (или IIS), вы получаете проблему, потому что угловые страницы не существуют на самом деле. Они "вычисляются" из углового маршрута.

есть несколько способов решить эту проблему. Один из них-использовать HashLocationStrategy предлагаемые угловой. Но в URL добавляется резкий знак. Это в основном для совместимости с Angular 1 (я предполагаю). Дело в том, что часть после sharp не является частью 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-скрипт. Мы просто проверяем, находится ли страница внутри каталога угловых приложений. Если это так, мы просто загружаем индекс.html напрямую (без перенаправления): это необходимо для сохранения URL-адреса без изменений. Мы также меняем код HTTP с 404 на 200 (Просто лучше для искателей).

Что делать, если страница не существует в угловой приложения? Ну, мы используем "поймать все" углового маршрутизатора (см. Угловая документация маршрутизатора).

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

Примечания:

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

это не постоянное исправление проблемы, но больше похоже на обходной путь или взломать

у меня была такая же проблема при развертывании моего углового приложения на gh-страницах. Сначала меня встретили 404 сообщения при обновлении моих страниц на gh-страницах.

затем, как указал @gunter, я начал использовать HashLocationStrategy который был обеспечен с угловым 2 .

но это пришло с его собственным набором проблем # в URL-адрес, он был очень плохо сделан URL-адрес выглядят странно, как это https://rahulrsingh09.github.io/AngularConcepts/#/faq.

я начал исследовать эту проблему и наткнулся на блог. Я попытался дать ему шанс, и это сработало .

вот что я сделал, как уже упоминалось в этом блоге.

вам нужно будет начать с добавления 404.html-файл для вашего РЕПО gh-pages это содержит пустой HTML-документ внутри него – но ваш документ должно составлять более 512 байт (объяснено ниже). Далее ставим после разметки в вашем 404.HTML-страницы головной элемент:

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

этот код устанавливает URL-адрес попытки входа в переменную на стандартный объект sessionStorage и сразу перенаправляет на ваш индекс проекта.html-страница с использованием тега meta refresh. Если вы делаете Сайт организации Github, не помещайте имя РЕПО в контент заменитель атрибутов текста, просто сделайте это: content= " 0; URL='/'"

для того, чтобы захватить и восстановить URL, который пользователь сначала перешел чтобы, вам понадобится чтобы добавить следующий тег скрипта в заголовок вашего индекс.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

угловые приложения являются идеальными кандидатами для обслуживания с помощью простого статического HTML-сервера. Вам не нужен серверный движок для динамического создания страниц приложения, потому что Angular делает это на стороне клиента.

Если приложение использует угловой маршрутизатор, необходимо настроить сервер для возврата страницы узла приложения (индекс.html) при запросе файла, которого у него нет.

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

нет никаких проблем, когда пользователь переходит к этому URL-адресу из запущенного клиента. Угловой маршрутизатор интерпретирует URL и маршруты к этой странице и герою.

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

статический сервер обычно возвращает индекс.html, когда он получает запрос наhttp://www.example.com/. но он отвергает http://www.example.com/heroes/42 и возвращает ошибку 404 - Not Found, если она не настроена для возврата индекса.html вместо

если этот проблема произошла в производстве, выполните следующие действия

1) добавить веб -.Конфигурационный файл в папке 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. В угловом-кли.json поставил Web.конфигурация в блоке активов, как показано ниже.

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

3) Теперь вы можете построить решение для производства с помощью

ng build --prod

это создаст папку dist. Файлы внутри папки dist готовы развертывание в любом режиме.

я исправил это (используя Java / Spring backend), добавив обработчик, который соответствует всему, что определено в моих угловых маршрутах, который отправляет обратно индекс.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";
    }
}

добавить импорт:

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

и в провайдере NgModule добавьте:

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

в основном индексе.html-файл приложения измените базовую href на ./index.html С /

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

ответ Саймона был правильным для меня. Я добавил этот код:

app.get('*', function(req, res, next) {
  res.sendfile("dist/index.html");
});