Угловой 2.0 маршрутизатор не работает при перезагрузке браузера
Я использую версию Angular 2.0.0-alpha.30. При перенаправлении на другой маршрут обновите браузер, показывая, что он не может GET / route.
Можете ли вы помочь мне понять, почему эта ошибка произошла.
- Как передать параметры запроса с помощью routerLink в новом Router V 3 alpha (владивосток)
- Angular2: Сделать дорожки нечувствительными к регистру
- Угловая ошибка 2: 404 возникает при обновлении через браузер
- Как использовать HashLocationStrategy с виджем Auth0 Lock для входа пользователя
- Возможна ли уклон 2 объекта через параметры маршрута?
- Угловой маршрутизатор поддерживает строку запроса
- Маршрут Angular 2's Router нарушен при использовании маршрутов HTML5?
- Как определить, как пользователь перемещается обратно в Angular2?
- Предупреждать пользователя о несохраненных изменениях перед выходом на страницу
- Как вернуться на предыдущую страницу
- Функция Angular2 canActivate (), вызывающая функцию async
- Как переключать макеты в Angular2
- Динамическая маршрутизация на основе внешних данных
Ошибка, которую вы видите, связана с тем, что вы запрашиваете http: // localhost / route, который не существует. По словам Саймона .
При использовании маршрутизации html5 вам необходимо сопоставить все маршруты в вашем приложении (в настоящее время 404) с index.html на вашей стороне сервера. Вот несколько вариантов для вас:
-
с использованием live-сервера: https://www.npmjs.com/package/live-server
$live-server --entry-file=index.html
-
с помощью nginx: http://nginx.org/en/docs/beginners_guide.html
error_page 404 /index.html
-
Tomcat – настройка web.xml. Из комментария Кунина
404 /index.html
Отказ от ответственности: это исправление работает с 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, и когда вы обновите его, он перезагрузится в нужном месте.
Надеюсь, это поможет!
Угловая по умолчанию использует pushstate HTML5 ( 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 final
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)
может также вызвать 404.
Вместо этого требуется
обновить для> = 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';
обновление для> = 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';
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 нарушение изменений
Я думаю, что ошибка, которую вы видите, связана с тем, что вы запрашиваете http: // localhost / route, который не существует. Вы должны убедиться, что ваш сервер будет отображать все запросы на главную страницу index.html.
Поскольку Angular 2 использует html5-маршрутизацию по умолчанию, а не использует hashи в конце URL-адреса, обновление страницы выглядит как запрос для другого ресурса.
Это обычная ситуация во всех версиях маршрутизатора, если вы используете страtagsю определения местоположения по умолчанию.
Что происходит, так это то, что URL-адрес на панели браузера является нормальным полным URL-адресом HTML, например, например: http://localhost/route
.
Поэтому, когда мы нажимаем Enter в строке браузера, на HTTP-сервер отправляется фактический HTTP-запрос, чтобы получить файл с именем route
.
На сервере нет такого файла, и на сервере не настроено что-то вроде express, чтобы обрабатывать запрос и предоставлять ответ, поэтому сервер возвращает 404 Not Found, потому что он не смог найти файл route
.
Нам бы хотелось, чтобы сервер возвращал файл index.html
содержащий одностраничное приложение. Затем маршрутизатор должен запускать и обрабатывать URL-адрес /route
и отображать отображаемый компонент.
Поэтому, чтобы исправить эту проблему, нам нужно настроить сервер для возврата index.html
(при условии, что это имя вашего файла приложения одной страницы) в случае, если запрос не может быть обработан, в отличие от 404 Not Found.
Способ сделать это будет зависеть от используемой технологии серверной стороны. Если его Java, например, вам, возможно, придется написать сервлет, в Rails он будет другим и т. Д.
Чтобы привести конкретный пример, если, например, вы используете NodeJs, вам придется написать такое промежуточное ПО:
function sendSpaFileIfUnmatched(req,res) { res.sendFile("index.html", { root: '.' }); }
И затем зарегистрируйте его в самом конце цепи промежуточного программного обеспечения:
app.use(sendSpaFileIfUnmatched);
Это будет служить index.html
вместо возврата 404, маршрутизатор начнет работать, и все будет работать так, как ожидалось.
Убедитесь, что это помещено в элемент head вашего index.html:
В примере в документации Angular2 Routing & Navigation вместо этого используется следующий код в голове (они объясняют, почему в примечании к примеру в реальном времени документации):
Когда вы обновляете страницу, это будет динамически устанавливать базовый href в текущую документацию. Я мог видеть, что это вызывает некоторую путаницу, когда люди просматривают документацию и пытаются воспроизвести плункер.
У меня была такая же проблема с использованием webpack-dev-сервера. Мне пришлось добавить параметр devServer в свой веб-пакет.
Решение:
// in webpack devServer: { historyApiFallback: true, stats: 'minimal' }
Если вы хотите иметь возможность вводить URL-адреса в браузере, не настраивая AppServer для обработки всех запросов к index.html, вы должны использовать HashLocationStrategy .
Самый простой способ настройки – использовать:
RouterModule.forRoot(routes, { useHash: true })
Вместо:
RouterModule.forRoot(routes)
С HashLocationStrategy ваши URL будут выглядеть так:
http://server:port/#/path
Мой сервер Apache, что я сделал, чтобы исправить 404, когда обновление или глубокая привязка очень проста. Просто добавьте одну строку в конфигурацию Apache vhost:
ErrorDocument 404 /index.html
Так что любая ошибка 404 будет перенаправлена на index.html, что и требует угловая2-маршрутизация.
Пример всего файла vhost:
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 AllowOverride All Options Indexes FollowSymLinks #Order allow,deny #Allow from All Require all granted 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"
Независимо от того, какой сервер вы используете, я думаю, что все дело в том, как настроить сервер на redirect 404 на ваш index.html.
Если вы используете Apache или Nginx в качестве сервера, вы должны создать .htaccess (если не созданный ранее) и «Вкл» RewriteEngine
RewriteEngine On RewriteCond% {DOCUMENT_ROOT}% {REQUEST_URI} -f [OR] RewriteCond% {DOCUMENT_ROOT}% {REQUEST_URI} -d RewriteRule ^ - [L] RewriteRule ^ /index.html
Конфигурация сервера не является решением для SPA, что я даже думаю. Вы не хотите перезагружать угловой SPA снова, если приходит неправильный маршрут, не так ли? Поэтому я не буду зависеть от маршрута сервера и перенаправлять на другой маршрут, но да, я дам index.html обрабатывать все запросы на угловые маршруты углового пути приложения.
Попробуйте это вместо других или неправильных маршрутов. Он работает для меня, не уверен, но кажется, что работа продолжается. Наткнулся на это сам, столкнувшись с проблемой.
@RouteConfig([ { path: '/**', redirectTo: ['MycmpnameCmp'] }, ... } ])
https://github.com/angular/angular/issues/4055
Однако не забудьте настроить свои серверные папки и права доступа, если у вас есть HTML или веб-скрипты, которые не являются СПА. Иначе вы столкнетесь с проблемами. Для меня, когда вы столкнулись с проблемой, подобной вам, это было сочетание конфигурации сервера и выше.
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
Для тех из нас, кто переживает жизнь в 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 (ссылка выше).
Вы можете попробовать ниже. Меня устраивает!
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 быстрого исправления, отредактируйте app.module.ts и добавьте {useHash:true}
после appRoutes.
@NgModule( { imports:[RouterModule.forRoot(appRoutes,{useHash:true})] })
Я хотел сохранить URL-адрес вспомогательных страниц в режиме HTML5 без перенаправления обратно в индекс, и ни одно из решений там не рассказывало мне, как это сделать, поэтому я сделал это:
Создайте простые виртуальные каталоги в IIS для всех ваших маршрутов и укажите их в корне приложения.
Оберните свой system.webServer в свой Web.config.xml с этим тегом местоположения, иначе вы получите дубликаты ошибок, загрузив Web.config во второй раз с помощью виртуального каталога:
Я проверил в угловом 2 семени, как это работает.
Вы можете использовать express-history-api-fallback для автоматического перенаправления при перезагрузке страницы.
Я думаю, что это самый элегантный способ решить эту проблему IMO.
Если вы хотите использовать PathLocationStrategy:
- Конфигурация Wildfly:
- Создайте файл entow-handlers.conf, который будет размещен в WEB-INF
- Содержание: (исключайте конечные точки restа!)
- regex [‘(. / overview / ?. ? $)’], а не regex [‘( ./ endpoints. )’] -> rewrite [‘/ index.html’]
- regex [‘(. / deployments / ?. ? $)’], а не regex [‘( ./ endpoints. )’] -> rewrite [‘/ index.html’]
Одностраничное приложение с Java EE / Wildfly: конфигурация на стороне сервера
Это неправильный ответ, но On-Refresh вы можете перенаправить все мертвые звонки на домашнюю страницу, жертвуя 404 страницей, это временный взлом, просто повторяющийся после файла 404.html
Лучшим решением для решения проблемы «роутер-не-работа на перезагрузке-браузером» является то, что мы должны использовать спа-спад. Если вы используете приложение angular2 с kernelм 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" }); });
2017-July-11: Поскольку это связано с вопросом, связанным с этой проблемой, но используя Angular 2 с Electron, я добавлю свое решение здесь.
Все, что мне нужно было сделать, это удалить
из моего index.html, и Electron снова перезагрузил страницу.
Ответ довольно сложный. Если вы используете простой старый Apache Server (или IIS), вы получаете проблему, потому что угловые страницы не существуют на самом деле. Они «вычисляются» по Угловому маршруту.
Существует несколько способов устранения проблемы. Один из них – использовать HashLocationStrategy, предлагаемую Angular. Но в URL добавляется острый знак. Это в основном для совместимости с Angular 1 (я полагаю). Факт является частью после того, как острый не является частью URL-адреса (тогда сервер разрешает часть перед знаком «#»). Это может быть идеально.
Здесь расширенный метод (основанный на трюке 404). Я предполагаю, что у вас есть «распределенная» версия вашего углового приложения ( ng build --prod
если вы используете Angular-CLI), и вы ng build --prod
доступ к страницам напрямую с вашим сервером, а PHP включен.
Если ваш сайт основан на страницах (например, WordPress), и у вас есть только одна папка, посвященная Angular (названная «dist» в моем примере), вы можете сделать что-то странное, но, в конце концов, просто. Я предполагаю, что вы сохранили свои угловые страницы в «/ dist» (с учетом
). Теперь используйте redirect 404 и помощь PHP.
В вашей конфигурации Apache (или в файле .htaccess
вашего каталога углового приложения) вы должны добавить ErrorDocument 404 /404.php
404.php начнется со следующего кода:
Not found."
где $angular
– это значение, хранящееся в HREF вашего углового index.html
.
Принцип довольно прост, если Apache не находит страницу, redirect 404 выполняется в скрипт PHP. Мы просто проверяем, находится ли страница в каталоге углового приложения. Если это так, мы просто загружаем index.html напрямую (без перенаправления): это необходимо для сохранения URL-адреса без изменений. Мы также меняем код HTTP с 404 до 200 (лучше для сканеров).
Что делать, если страница не существует в угловом приложении? Ну, мы используем «улавливать все» углового маршрутизатора (см. Документацию по угловому маршрутизатору).
Этот метод работает со встроенным угловым приложением внутри базового веб-сайта (я думаю, что это будет иметь место в будущем).
ЗАМЕТКИ:
- Попытка сделать то же самое с
mod_redirect
(путем переписывания URL-адресов) вовсе не является хорошим решением, потому что файлы (например, активы) должны быть действительно загружены, то это гораздо более рискованно, чем просто использование «не найденного» решения. - Просто redirect с использованием
ErrorDocument 404 /dist/index.html
работает, но Apache все еще отвечает кодом ошибки 404 (что плохо для сканеров).
Это не постоянное исправление проблемы, а скорее как обходной путь или взлом
У меня была такая же проблема при развертывании моего приложения Angular для gh-страниц. Сначала я был встречен 404 сообщениями при обновлении моих страниц на gh-страницах.
Затем, как заметил @gunter, я начал использовать HashLocationStrategy
которая была снабжена Angular 2.
Но это пришло с собственным набором проблем. #
В URL-адресе было действительно плохо, поэтому url выглядел странно, как https://rahulrsingh09.github.io/AngularConcepts/#/faq
.
Я начал изучать эту проблему и наткнулся на блог. Я попытался дать ему шанс, и это сработало.
Вот что я сделал, как упоминалось в этом блоге.
Вам нужно будет начать с добавления файла 404.html в repository gh-pages, который содержит пустой HTML-документ внутри него, но ваш документ должен содержать более 512 байт (объясняется ниже). Затем поместите следующую разметку в элемент заголовка страницы 404.html:
Этот код устанавливает попытку ввода URL-адреса переменной в стандартном объекте sessionStorage и немедленно перенаправляет на страницу index.html вашего проекта с помощью тега meta refresh. Если вы делаете сайт организации Github, не помещайте имя репо в текст-заменитель атрибута контента, просто выполните следующее: content = “0; URL = ‘/'”
Чтобы захватить и восстановить URL-адрес, с которого первоначально перешел пользователь, вам нужно добавить следующий тег скрипта в начало страницы index.html, прежде чем какие-либо другие действия JavaScript будут действовать в текущем состоянии страницы:
Этот бит JavaScript извлекает URL-адрес, который мы кэшировали в sessionStorage на странице 404.html, и заменяет его текущую запись истории.
Ссылка backalleycoder Благодаря @Daniel для этого обходного пути.
Теперь указанный URL-адрес изменяется на https://rahulrsingh09.github.io/AngularConcepts/faq
Угловые приложения – идеальные кандидаты для работы с простым статическим HTML-сервером. Вам не нужен серверный движок для динамической компоновки страниц приложения, потому что 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 вашего углового приложения. Поместите в него код ниже.
2) Добавьте ссылку на него в angular-cli.json. В angular-cli.json введите Web.config в блок активов, как показано ниже.
"assets": [ "assets", "favicon.ico", "Web.config" ],
3) Теперь вы можете построить решение для производства, используя
ng build --prod
Это создаст папку dist. Файлы в папке dist готовы для развертывания в любом режиме.
Я исправил это (используя бэкэнд Java / Spring), добавив обработчик, который соответствует всему, определенному в моих Углеродных маршрутах, который отправляет обратно index.html вместо 404. Это тогда эффективно (re) загружает приложение и загружает правильную страницу. У меня также есть обработчик 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}]
В главном файле index.html файла приложения измените базовый href на ./index.html
из /
Приложение при развертывании на любом сервере даст реальный URL-адрес для страницы, к которой можно получить доступ из любого внешнего приложения.
Ответ Саймона был прав для меня. Я добавил этот код:
app.get('*', function(req, res, next) { res.sendfile("dist/index.html"); });