Angular 2.0 routeur ne fonctionne pas sur le rechargement du navigateur

J’utilise la version Angular 2.0.0-alpha.30. Lorsque vous redirigez vers un autre itinéraire, actualisez le navigateur, son affichage ne peut pas GET / route.

Pouvez-vous m’aider à comprendre pourquoi cette erreur s’est produite.

L’erreur que vous rencontrez est que vous demandez http: // localhost / route qui n’existe pas. Selon Simon .

Lorsque vous utilisez le routage html5, vous devez mapper tous les itinéraires de votre application (actuellement 404) sur index.html du côté serveur. Voici quelques options pour vous:

  1. en utilisant live-server: https://www.npmjs.com/package/live-server

    $live-server --entry-file=index.html

  2. en utilisant nginx: http://nginx.org/en/docs/beginners_guide.html

    error_page 404 /index.html

  3. Tomcat – configuration de web.xml. Du commentaire de Kunin

    404 /index.html

Disclaimer: cette correction fonctionne avec Alpha44

J’ai eu le même problème et l’ ai résolu en implémentant le HashLocationStrategy répertorié dans la prévisualisation de l’API Angular.io.

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

Commencez par importer les directives nécessaires

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

Et enfin, amorcez le tout comme ça

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

Votre itinéraire apparaîtra sous la forme http: // localhost / # / route et, lorsque vous actualiserez, il se rechargera à sa place.

J’espère que cela pourra aider!

Angular par défaut utilise HTML5 pushstate ( PathLocationStrategy en argot angular).
Vous avez besoin soit d’un serveur qui traite toutes les demandes comme s’il demandait index.html soit vous HashLocationStrategy à HashLocationStrategy (avec # dans l’URL des routes) https://angular.io/docs/ts/latest/api/common/index/ HashLocationStrategy-class.html

Voir aussi https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/

Pour passer à l’utilisation de HashLocationStrategy

mise à jour pour> = RC.5 et 2.0.0 final

 import {HashLocationStrategy, LocationStrategy} from '@angular/common'; @NgModule({ declarations: [AppCmp], bootstrap: [AppCmp], imports: [BrowserModule, routes], providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}] ]); 

ou plus court avec useHash

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

Assurez-vous d’avoir toutes les importations requirejses

Pour le nouveau routeur (RC.3)

  

peut également provoquer 404.

Il nécessite à la place

  

mise à jour pour> = 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'; 

mise à jour pour> = beta.16 Les importations ont changé

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

Voir aussi https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26 changements de rupture

Je pense que l’erreur que vous voyez est parce que vous demandez http: // localhost / route qui n’existe pas. Vous devez vous assurer que votre serveur mappera toutes les demandes sur votre page index.html principale.

Comme Angular 2 utilise le routage html5 par défaut plutôt que d’utiliser des hachages à la fin de l’URL, l’actualisation de la page ressemble à une demande pour une autre ressource.

Ceci est une situation courante dans toutes les versions de routeur si vous utilisez la stratégie de localisation HTML par défaut.

Qu’est-ce qui se passe est que l’URL sur la barre de navigateur est une URL HTML complète normale, comme par exemple: http://localhost/route .

Donc, lorsque nous cliquons sur Entrée dans la barre du navigateur, une requête HTTP réelle est envoyée au serveur pour obtenir un fichier nommé route .

Le serveur ne dispose pas d’un tel fichier et aucun élément comme express n’est configuré sur le serveur pour gérer la demande et fournir une réponse. Le serveur renvoie donc 404 non trouvé car il n’a pas pu trouver le fichier de route .

Ce que nous voudrions, c’est que le serveur retourne le fichier index.html contenant l’application à une seule page. Le routeur doit alors lancer et traiter l’URL /route et afficher le composant mappé.

Donc, pour résoudre le problème, nous devons configurer le serveur pour qu’il renvoie index.html (en supposant qu’il s’agisse du nom de votre fichier d’application à une page) au cas où la requête ne pourrait pas être traitée, par opposition à 404 Not Found.

La manière de procéder dépend de la technologie côté serveur utilisée. Si son Java par exemple, vous pourriez avoir à écrire un servlet, dans Rails cela sera différent, etc.

Pour donner un exemple concret, si par exemple vous utilisez NodeJs, vous devrez écrire un middleware comme celui-ci:

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

Et puis enregistrez-le à la toute fin de la chaîne de middleware:

 app.use(sendSpaFileIfUnmatched); 

Cela servira index.html au lieu de renvoyer un 404, le routeur démarrera et tout fonctionnera comme prévu.

Assurez-vous que ceci est placé dans l’élément head de votre index.html:

  

L’ exemple de la documentation Angular2 Routing & Navigation utilise plutôt le code suivant dans la tête (ils expliquent pourquoi, dans l’exemple de note de la documentation):

  

Lorsque vous actualisez une page, cela définit dynamicment la base href sur votre document.location actuel. Je pouvais voir cela provoquer une certaine confusion pour les personnes parcourant la documentation et essayant de reproduire le plunker.

J’ai eu le même problème avec l’utilisation de webpack-dev-server. J’ai dû append l’option devServer à mon webpack.

Solution:

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

Si vous voulez pouvoir entrer des URL dans le navigateur sans configurer votre AppServer pour gérer toutes les demandes à index.html, vous devez utiliser HashLocationStrategy .

Le moyen le plus simple de configurer consiste à utiliser:

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

Au lieu de:

 RouterModule.forRoot(routes) 

Avec HashLocationStrategy, vos URL seront les suivantes:

 http://server:port/#/path 

Mon serveur est Apache, ce que j’ai fait pour corriger 404 quand rafraîchir ou relier en profondeur est très simple. Ajoutez simplement une ligne dans apache vhost config:

 ErrorDocument 404 /index.html 

Pour que toute erreur 404 soit redirigée vers index.html, ce que veut dire le routage angular2.

L’exemple de fichier vhost entier:

  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"  

Quel que soit le serveur que vous utilisez, je pense que l’essentiel est de trouver des moyens de configurer le serveur pour redirect le 404 vers votre index.html.

Si vous utilisez Apache ou Nginx en tant que serveur, vous devez créer un fichier .htaccess (s’il n’est pas créé auparavant) et “On” RewriteEngine


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

La configuration du serveur n’est pas une solution pour un SPA, c’est ce que je pense même. Vous ne voulez pas recharger un spa angular à nouveau si un mauvais itinéraire arrive, n’est-ce pas? Je ne vais donc pas dépendre d’une route de serveur et redirect vers une autre route, mais oui, je laisserai index.html gérer toutes les requêtes de routes angulars du chemin d’application angular.

Essayez ceci plutôt que des routes différentes ou erronées. Cela fonctionne pour moi, pas sûr mais semble être un travail en cours. J’ai trébuché moi-même face à un problème.

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

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

Cependant, n’oubliez pas de configurer les dossiers de votre serveur et d’accéder aux droits si vous avez des scripts HTML ou Web qui ne sont pas des SPA. Sinon, vous rencontrerez des problèmes. Pour moi, face à un problème comme vous, c’était un mélange de configuration de serveur et plus.

 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 

Pour ceux d’entre nous qui traversent la vie dans IIS: utilisez le code PowerShell suivant pour résoudre ce problème en vous basant sur les documents officiels Angular 2 (que quelqu’un a posté sur ce sujet? 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 

Cela redirige le 404 vers le fichier /index.html selon la suggestion dans les documents Angular 2 (lien ci-dessus).

Vous pouvez essayer ci-dessous. Ça marche pour moi!

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: ssortingng = window.location.hash; if (path && path.length > 0) { this.router.navigate([path.substr(2)]); } } public ngOnInit() { } } 

Vous pouvez encore améliorer path.substr (2) pour diviser en parameters de routeur. J’utilise angular 2.4.9

pour la correction angular 5 rapide, éditez app.module.ts et ajoutez {useHash:true} après les appRoutes.

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

Je voulais conserver le chemin d’URL des sous-pages en mode HTML5 sans une redirection vers l’index et aucune des solutions disponibles ne m’a dit comment procéder, c’est ainsi que je l’ai fait:

Créez des répertoires virtuels simples dans IIS pour tous vos itinéraires et pointez-les vers la racine de l’application.

Enveloppez votre system.webServer dans votre Web.config.xml avec cette balise d’emplacement, sinon vous obtiendrez des erreurs en double lors du chargement de Web.config une seconde fois avec le répertoire virtuel:

            

J’ai vérifié en angular 2 semences comment cela fonctionne.

Vous pouvez utiliser express-history-api-fallback pour redirect automatiquement lorsqu’une page est rechargée.

Je pense que c’est la manière la plus élégante de résoudre ce problème.

Si vous souhaitez utiliser PathLocationStrategy:

  • Configuration Wildfly:
    • Créer un fichier undertow-handlers.conf à placer dans le WEB-INF
    • Contenu: (excluez vos points d’extrémité restants!)
      • regex [‘(. / overview / ?. ? $)’] et non regex [‘(. / endpoints. )’] -> rewrite [‘/ index.html’]
      • regex [‘(. / deployments / ?. ? $)’ et non regex [‘(. / endpoints. )’] -> rewrite [‘/ index.html’]

Application à page unique avec Java EE / Wildfly: configuration côté serveur

Ce n’est pas la bonne réponse, mais sur-refresh, vous pouvez redirect tous les appels morts vers la page d’accueil en sacrifiant la page 404.

       

La meilleure solution pour résoudre le problème du “routeur-ne-pas-travailler-sur-recharger-le-navigateur” est que nous devons utiliser spa-back. Si vous utilisez l’application angular2 avec le kernel asp.net, nous devons la définir sur la page “StartUp.cs”. sous les routages MVC. Je joins le code.

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

2017-11-juillet: Puisque ceci est lié à une question ayant ce problème mais en utilisant Angular 2 avec Electron, j’appendai ma solution ici.

Tout ce que j’avais à faire était de supprimer de mon index.html et Electron a recommencé à recharger la page.

La réponse est assez délicate. Si vous utilisez un ancien serveur Apache (ou IIS), vous rencontrez le problème car les pages angulars n’existent pas réellement. Ils sont “calculés” à partir de l’itinéraire angular.

Il existe plusieurs façons de résoudre le problème. L’une consiste à utiliser le HashLocationStrategy proposé par Angular. Mais un signe net est ajouté dans l’URL. Ceci est principalement pour la compatibilité avec Angular 1 (je suppose). Le fait est que la partie après le dièse ne fait pas partie de l’URL (alors le serveur résout la partie avant le signe “#”). Cela peut être parfait.

Voici une méthode améliorée (basée sur l’astuce 404). Je suppose que vous avez une version “dissortingbuée” de votre application angular ( ng build --prod si vous utilisez Angular-CLI) et que vous accédez directement aux pages avec votre serveur et que PHP est activé.

Si votre site est basé sur des pages (WordPress par exemple) et que vous n’avez qu’un seul dossier dédié à Angular (nommé “dist” dans mon exemple), vous pouvez faire quelque chose de bizarre mais, à la fin, simple. Je suppose que vous avez stocké vos pages angulars dans “/ dist” (avec le ). Utilisez maintenant une redirection 404 et l’aide de PHP.

Dans votre configuration Apache (ou dans le fichier .htaccess de votre répertoire d’application angular), vous devez append ErrorDocument 404 /404.php

Le 404.php commencera par le code suivant:

 Not found." 

$angular est la valeur stockée dans le HREF de votre index.html angular.html.

Le principe est assez simple, si Apache ne trouve pas la page, une redirection 404 est faite vers le script PHP. Nous vérifions simplement si la page se trouve dans le répertoire de l’application angular. Si c’est le cas, il suffit de charger directement l’index.html (sans redirection): cela est nécessaire pour conserver l’URL inchangée. Nous modifions également le code HTTP de 404 à 200 (juste mieux pour les robots d’exploration).

Que faire si la page n’existe pas dans l’application angular? Eh bien, nous utilisons le “catch all” du routeur angular (voir la documentation du routeur angular).

Cette méthode fonctionne avec une application Angular intégrée dans un site Web de base (je pense que ce sera le cas à l’avenir).

REMARQUES:

  • Essayer de faire la même chose avec mod_redirect (en réécrivant les URL) n’est pas du tout une bonne solution car les fichiers (comme les actifs) doivent être vraiment chargés, alors il est beaucoup plus risqué que d’utiliser la solution “introuvable”.
  • Il suffit de redirect en utilisant ErrorDocument 404 /dist/index.html , mais Apache répond toujours avec un code d’erreur 404 (ce qui est mauvais pour les robots).

Ce n’est pas un correctif permanent pour le problème, mais plutôt comme une solution de contournement ou un hack

J’ai eu ce même problème lors du déploiement de mon application angular sur gh-pages. J’ai d’abord été accueilli avec 404 messages lors de l’actualisation de mes pages sur les pages Gh.

Puis, comme l’a fait remarquer @gunter, j’ai commencé à utiliser HashLocationStrategy qui était fourni avec Angular 2.

Mais cela venait avec son propre ensemble de problèmes, le # dans l’URL était vraiment mauvais, ce qui rendait l’url bizarre comme ceci https://rahulrsingh09.github.io/AngularConcepts/#/faq .

J’ai commencé à faire des recherches sur ce problème et je suis tombé sur un blog. J’ai essayé de lui donner un coup et ça a fonctionné.

Voici ce que j’ai fait comme mentionné dans ce blog.

Vous devez commencer par append un fichier 404.html à votre repository gh-pages contenant un document HTML vide, mais votre document doit contenir plus de 512 octets (expliqué ci-dessous). Ensuite, mettez le balisage suivant dans l’élément head de votre page 404.html:

   

Ce code définit l’URL d’entrée tentée sur une variable de l’object sessionStorage standard et redirige immédiatement vers la page index.html de votre projet à l’aide d’une balise meta refresh. Si vous faites un site d’organisation Github, ne mettez pas de nom de repo dans le texte de remplacement de l’atsortingbut de contenu, procédez comme suit: content = “0; URL = ‘/'”

Pour capturer et restaurer l’URL dans laquelle l’utilisateur a initialement navigué, vous devez append la balise de script suivante à la tête de votre page index.html avant que tout autre code JavaScript n’agisse sur l’état actuel de la page:

  

Ce bit JavaScript récupère l’URL que nous avons mis en cache dans sessionStorage sur la page 404.html et remplace l’entrée d’historique actuelle par celle-ci.

Référence backalleycoder Merci à @Daniel pour cette solution de contournement.

Maintenant, l’URL ci-dessus change pour https://rahulrsingh09.github.io/AngularConcepts/faq

Les applications angulars sont des candidats parfaits pour servir avec un serveur HTML statique simple. Vous n’avez pas besoin d’un moteur côté serveur pour composer dynamicment les pages d’application, car Angular le fait côté client.

Si l’application utilise le routeur angular, vous devez configurer le serveur pour qu’il renvoie la page hôte de l’application (index.html) lorsque le fichier lui est demandé.

Une application routée devrait prendre en charge les “liens profonds”. Un lien profond est une URL qui spécifie un chemin d’access à un composant à l’intérieur de l’application. Par exemple, http://www.example.com/heroes/42 est un lien profond vers la page de détails sur les héros qui affiche le héros avec l’ID: 42.

Il n’y a pas de problème lorsque l’utilisateur navigue vers cette URL depuis un client en cours d’exécution. Le routeur angular interprète l’URL et les itinéraires vers cette page et ce héros.

Mais en cliquant sur un lien dans un e-mail, en le saisissant dans la barre d’adresse du navigateur ou simplement en actualisant le navigateur sur la page de détails des héros, toutes ces actions sont gérées par le navigateur, en dehors de l’application en cours. Le navigateur envoie une demande directe au serveur pour cette URL, en contournant le routeur.

Un serveur statique renvoie systématiquement index.html lorsqu’il reçoit une demande pour http://www.example.com/ . Mais il rejette http://www.example.com/heroes/42 et renvoie une erreur 404 – Not Found, sauf s’il est configuré pour retourner index.html à la place

Si ce problème est survenu en production, suivez les étapes ci-dessous.

1) Ajoutez un fichier Web.Config dans le dossier src de votre application angular. Placez le code ci-dessous.

                 

2) Ajouter une référence dans angular-cli.json. Dans angular-cli.json, placez Web.config dans le bloc de ressources, comme indiqué ci-dessous.

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

3) Maintenant, vous pouvez construire la solution pour la production en utilisant

 ng build --prod 

Cela va créer un dossier dist. Les fichiers contenus dans le dossier dist sont prêts à être déployés par n’importe quel mode.

J’ai corrigé ceci (en utilisant un backend Java / Spring) en ajoutant un gestionnaire qui correspond à tout ce qui est défini dans mes routes Angular, qui renvoie index.html au lieu de 404. Ceci (re) amorce effectivement l’application et charge la bonne page. J’ai aussi un gestionnaire 404 pour tout ce qui n’est pas pris par cela.

 @Controller ////don't use RestController or it will just send back the ssortingng "index.html" public class Redirect { private static final Logger logger = LoggerFactory.getLogger(Redirect.class); @RequestMapping(value = {"comma", "sep", "list", "of", "routes"}) public Ssortingng 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"; } } 

Ajouter des importations:

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

Et dans le fournisseur NgModule, ajoutez:

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

Dans le fichier principal index.html, le fichier de l’application modifie la base href en ./index.html partir de /

Lorsqu’elle est déployée sur n’importe quel serveur, l’application donnera une URL réelle pour la page, accessible à partir de n’importe quelle application externe.

La réponse de Simon était correcte pour moi. J’ai ajouté ce code:

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