web-dev-qa-db-fra.com

Angular Une erreur 2: 404 se produit lors de l'actualisation via le navigateur.

Je suis nouveau dans Angular 2. J'ai enregistré mon application de page unique sur mon serveur dans un dossier nommé "myapp". J'ai changé l'URL dans la base en http://example.com/myapp/ `.

Mon projet a deux pages. J'ai donc implémenté le routage Angular 2. Je règle la page par défaut comme login. Lorsque je tape http://example.com/myapp/ dans mon navigateur, il sera automatiquement redirigé vers http://example.com/myapp/login. Mais si vous actualisez cette page, une erreur 404 apparaît, indiquant que http://example.com/myapp/login n'est pas trouvé.

Mais si je lance mon projet en utilisant le serveur lite, tout fonctionne. Dans ce cas, indiquez l'URL dans index.html "/". Comment le réparer?

152
DAN

En fait, il est normal que vous ayez une erreur 404 lors de l'actualisation de votre application car l'adresse réelle dans le navigateur est mise à jour (et sans approche #/hashbang). Par défaut, l'historique HTML5 est utilisé pour la réutilisation dans Angular2.

Pour corriger l'erreur 404, vous devez mettre à jour votre serveur afin qu'il serve le fichier index.html pour chaque chemin de route que vous avez défini.

Si vous souhaitez passer à l'approche HashBang, vous devez utiliser cette configuration:

import {bootstrap} from 'angular2/platform/browser';
import {provide} from 'angular2/core';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';

import {MyApp} from './myapp';

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

Dans ce cas, lorsque vous actualiserez la page, elle sera affichée à nouveau (mais vous aurez un # dans votre adresse).

Ce lien pourrait également vous aider: Lorsque j'actualise mon site, je reçois un 404. C'est avec Angular2 et firebase .

J'espère que ça vous aide, Thierry

115
Thierry Templier

Mise à jour pour la version angulaire 2 finale

Dans app.module.ts:

  • Ajouter des importations:

    import { HashLocationStrategy, LocationStrategy } from '@angular/common';
    
  • Et dans le fournisseur NgModule, ajoutez:

    {provide: LocationStrategy, useClass: HashLocationStrategy}
    

Exemple (app.module.ts):

import { NgModule }       from '@angular/core';
import { BrowserModule  } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
import { HashLocationStrategy, LocationStrategy } from '@angular/common';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule],
    providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
    bootstrap: [AppComponent],
})
export class AppModule {}

Alternative

Utilisez RouterModule.forRoot avec l'argument {useHash: true}.

Exemple: (de documents angulaires )

import { NgModule } from '@angular/core';
...

const routes: Routes = [//routes in here];

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    RouterModule.forRoot(routes, { useHash: true })
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
221
Asaf Hananel

Pour les personnes (comme moi) qui veulent vraiment PathLocationStrategy (c'est-à-dire html5Mode) au lieu de HashLocationStrategy, voir Comment: configurer votre serveur pour qu'il fonctionne avec html5Mode depuis un wiki tiers:

Lorsque html5Mode est activé, le caractère # ne sera plus utilisé dans vos URL. Le symbole # est utile car il ne nécessite aucune configuration côté serveur. Sans #, l'URL a l'air beaucoup plus jolie, mais elle nécessite également des réécritures côté serveur.

Ici, je ne copie que trois exemples du wiki, au cas où le wiki serait perdu. Vous pouvez trouver d’autres exemples en recherchant le mot clé "Réécriture d’URL" (par exemple, cette réponse pour Firebase).

Apache

<VirtualHost *:80>
    ServerName my-app

    DocumentRoot /path/to/app

    <Directory /path/to/app>
        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]
    </Directory>
</VirtualHost>

Documentation pour le module de réécriture

nginx

server {
    server_name my-app;

    root /path/to/app;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Documentation pour try_files

IIS

<system.webServer>
  <rewrite>
    <rules> 
      <rule name="Main Rule" 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>
94
Franklin Yu

J'ai eu le même problème. Mon application Angular s'exécute sur un serveur Windows.

J'ai résolu ce problème en créant un fichier web.config dans le répertoire racine.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" 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>
24
Bennie-be

Peut-être que vous pouvez le faire en enregistrant votre racine avec RouterModule. Vous pouvez passer un deuxième objet avec la propriété "useHash: true" comme ci-dessous:

import { NgModule }       from '@angular/core';
import { BrowserModule  } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
import { ROUTES }   from './app.routes';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule],
    RouterModule.forRoot(ROUTES ,{ useHash: true }),],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}
18
Niyaz

Pour les personnes qui lisent ceci et qui utilisent Angular 2 rc4 ou version ultérieure, il apparaît que LocationStrategy a été déplacé du routeur au commun. Vous devrez l'importer à partir de là.

Notez également les accolades autour de la ligne "fournir".

main.ts

// Imports for loading & configuring the in-memory web api
import { XHRBackend } from '@angular/http';

// The usual bootstrapping imports
import { bootstrap }      from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';

import { AppComponent }         from './app.component';
import { APP_ROUTER_PROVIDERS } from './app.routes';
import { Location, LocationStrategy, HashLocationStrategy} from '@angular/common';

bootstrap(AppComponent, [
    APP_ROUTER_PROVIDERS,
    HTTP_PROVIDERS,
    {provide: LocationStrategy, useClass: HashLocationStrategy}
]);
5
Koen De Couck

Si vous exécutez Angular 2 via ASP.NET Core 1 dans Visual Studio 2015, cette solution de Jürgen Gutsch pourrait être utile. Il le décrit dans n article de blog . C'était la meilleure solution pour moi. Placez le code C # fourni ci-dessous dans votre répertoire public Startup.cs Configure () juste avant app.UseStaticFiles ();

app.Use( async ( context, next ) => {
    await next();

    if( context.Response.StatusCode == 404 && !Path.HasExtension( context.Request.Path.Value ) ) {
        context.Request.Path = "/index.html";
        await next();
    }
});
5
StackOverflowUser