Il router Angular 2.0 non funziona nel ricaricare il browser


190

Sto usando la versione Angular 2.0.0-alpha.30. Quando reindirizza a una route diversa, quindi aggiorna il browser, mostrando Cannot GET / route.

Potete aiutarmi a capire perché questo errore si è verificato.



Grazie per la risposta, ma quella è per le versioni angolari 1.x. Sto affrontando il problema in Angular 2.0.
Vinz e Tonz,

1
La domanda collegata è un problema generale con pushState non specifico angolare. La tua domanda non fornisce informazioni sufficienti per sapere se è correlata.
Günter Zöchbauer,

5
Angular 2.0 utilizza un router completamente nuovo, quindi il post collegato non è più utile dal momento che è il vecchio router
Vinz e Tonz,

Come ho detto, se si tratta del problema pushState, non è specifico di Angular e non può essere risolto da Angular ma deve essere risolto sul server.
Günter Zöchbauer,

Risposte:


141

L'errore che stai vedendo è perché stai richiedendo http: // localhost / route che non esiste. Secondo Simone .

Quando si utilizza il routing html5 è necessario mappare tutti i percorsi nell'app (attualmente 404) su index.html sul lato server. Ecco alcune opzioni per te:

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

    $live-server --entry-file=index.html`
    
  2. usando nginx: http://nginx.org/en/docs/beginners_guide.html

    error_page 404 /index.html
    
  3. Tomcat - configurazione di web.xml. Dal commento di Kunin

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

1
Poiché è necessario il supporto lato server per il routing html5, questo funziona perfettamente. Grazie
Prabhat,

Posso usare nginx come proxy per pub serve? In questo modo non ho bisogno di pub buildmolto durante lo sviluppo. Ho provato ma proxy_passnon funziona molto bene con error_page.
Franklin Yu,

@FranklinYu non l'ho mai fatto prima. Lo risolvi?
Quy Tang,

1
Usando nginx. , error_page 404 /index.html nella posizione dell'app ha funzionato per me. Grazie.
Richard K. Campion,

2
Tomcat - configurazione di web.xml <error-page> <error-code> 404 </error-code> <location> /index.html </location> </error-page>
A Kunin

65

Disclaimer: questa correzione funziona con Alpha44

Ho avuto lo stesso problema e risolto implementando HashLocationStrategy elencato nell'anteprima dell'API di Angular.io.

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

Inizia importando le direttive necessarie

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

E infine, avvia tutto insieme in questo modo

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

Il percorso verrà visualizzato come http: // localhost / # / route e quando si aggiorna, verrà ricaricato nella posizione corretta.

Spero che aiuti!


1
questo codice funzionerà bene ma c'è qualche problema in questa tecnica usando questo #verrà aggiunto automaticamente nell'URL. c'è qualche soluzione per rimuovere # dall'URL usando questo?
Pardeep Jain,

D'accordo, ho provato ad implementare "PathLocationStrategy" elencato qui , ma non sono riuscito a farlo funzionare. Un URL senza il #sarebbe ottimale.
SimonHawesome

Sì, anch'io ho provato lo stesso con il PathLocationStrategyma questo non funziona per me. o ho usato un metodo sbagliato o non so come usare PathLocationStrategy.
Pardeep Jain,

1
Questo non funziona per me in RC1. L'importazione di LocationStrategy, HashLocationStrategy da "@ angular / router" non riesce.
infojolt

1
Ci scusiamo per tornare a questa domanda dopo più di 1 anno :) Ma HashLocationStrategy aiuta a rimanere sullo stesso percorso del router? Nel mio caso, quando aggiorno, mi porta a localhost / # / < route predefinita > vale a dire la route predefinita per la home page. Come si procede al percorso corrente su cui mi trovavo originariamente quando sono stato "aggiornato"?
rajugaadu,

47

Angular per impostazione predefinita utilizza HTML5 pushstate ( PathLocationStrategyin gergo angolare).
O hai bisogno di un server che elabori tutte le richieste come stava richiedendo index.htmlo passi a HashLocationStrategy(con # nell'URL per le rotte) https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class. html

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

Per passare a HashLocationStrategyutilizzare

aggiornamento per> = RC.5 e 2.0.0 final

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

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

o più corto con useHash

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

assicurarsi di avere tutte le importazioni richieste

Per il nuovo router (RC.3)

<base href="."> 

può causare anche 404.

Richiede invece

<base href="/">

aggiornamento per> = 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';  

aggiornamento per> = beta.16 Le importazioni sono state modificate

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

<beta.16

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

Vedi anche https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26 breaking-changes


1
Grazie! fornire sembra essersi spostato sotto angolare / core: importare {fornire} da 'angular2 / core'
StrangeLoop

1
Solo per notare: update for >= RC.x(RC.2) funziona router 3.0.0-alpha.7, ma provideannotato come deprecato senza informazioni su quale funzione lo ha sostituito.
Mrusful,

Usa{provide: SomeClass, useClass: OtherClass}
Günter Zöchbauer il

2
Risposta più aggiornata Per l'ultima versione di Angular 2.4.1 avevo <base href = "./">. Modificato in <base href = "/"> risolto il problema che avevo. Potrebbe essere utile per qualcuno.
Saiyaff Farouk,

28

Penso che l'errore che stai vedendo sia perché stai richiedendo http: // localhost / route che non esiste. Devi assicurarti che il tuo server mapperà tutte le richieste sulla tua pagina index.html principale.

Poiché Angular 2 utilizza il routing html5 per impostazione predefinita anziché utilizzare gli hash alla fine dell'URL, l'aggiornamento della pagina sembra una richiesta per una risorsa diversa.


7
quindi come possiamo risolverlo? come mappiamo tutte le richieste all'indice principale per impostazione predefinita? dipende dal server?
Ayyash,

1
Sì, lo faresti sul server con qualsiasi framework web che stai utilizzando. L'alternativa è utilizzare HashLocationStrategy come descritto di seguito.
Simon,

Ricaricherai la SPA angolare in ogni percorso non presente. È come dovrebbe essere gestito?
Gary

Ricarica solo se l'utente fa clic su Aggiorna nel browser, non quando l'utente cambia rotta attraverso l'interfaccia utente. Non è affatto possibile aggirare una ricarica quando l'utente aggiorna.
Wallace Howery,

19

Questa è una situazione comune in tutte le versioni di router se si utilizza la strategia di posizione HTML predefinita.

Quello che succede è che l'URL sulla barra del browser è un normale URL HTML completo, come ad esempio: http://localhost/route .

Pertanto, quando si preme Invio nella barra del browser, viene inviata una richiesta HTTP effettiva al server per ottenere un file denominato route.

Il server non ha tale file e né qualcosa come express è configurato sul server per gestire la richiesta e fornire una risposta, quindi il server restituisce 404 Not Found, perché non è riuscito a trovare il route file.

Quello che vorremmo è che il server restituisca il index.htmlfile contenente l'applicazione a pagina singola. Quindi il router dovrebbe avviare ed elaborare il/route URL e visualizzare il componente associato ad esso.

Quindi, per risolvere il problema, dobbiamo configurare il server in modo che ritorni index.html (supponendo che sia il nome del file dell'applicazione a pagina singola) nel caso in cui la richiesta non possa essere gestita, al contrario di un 404 non trovato.

Il modo per farlo dipenderà dalla tecnologia lato server utilizzata. Se ad esempio è Java, potresti dover scrivere un servlet, in Rails sarà diverso, ecc.

Per fare un esempio concreto, se per esempio stai usando NodeJs, dovresti scrivere un middleware come questo:

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

E quindi registrarlo alla fine della catena del middleware:

app.use(sendSpaFileIfUnmatched);

Questo servirà index.htmlinvece di restituire un 404, il router si avvierà e tutto funzionerà come previsto.


Questo era esattamente il mio problema. Se usi NGINX, questa risposta aiuta a risolverlo: stackoverflow.com/questions/7027636/…
Nathan

Esiste un tutorial su come eseguire questa operazione per Java? Grazie.
000000000000000000000

13

Assicurati che sia posizionato nell'elemento head del tuo index.html:

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

L' esempio nella documentazione di routing e navigazione di Angular2 utilizza invece il seguente codice nell'intestazione (spiegano perché nella nota di esempio dal vivo della documentazione):

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

Quando aggiorni una pagina, questo imposterà dinamicamente l'href di base sul tuo documento.locazione corrente. Ho potuto vedere questo causando un po 'di confusione per le persone che scremano la documentazione e provano a replicare il plunker.


Grazie per averlo condiviso. Cerchiamo di essere chiari, ha funzionato solo per me quando ho messo <base href = "/"> direttamente dopo aver caricato tutti i CSS in <head> e prima di caricare QUALSIASI file Js. Spero che possa aiutare chiunque
wmehanna,

ho <base href = "./"> in index.html quindi rimosso '.' dall'href e ha funzionato ..
Saurabh Solanki,

10

Se vuoi essere in grado di inserire gli URL nel browser senza configurare il tuo AppServer per gestire tutte le richieste su index.html, devi usare HashLocationStrategy .

Il modo più semplice per configurare è usare:

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

Invece di:

RouterModule.forRoot(routes)

Con HashLocationStrategy i tuoi URL saranno come:

http://server:port/#/path

Grazie! questo aiuta, ma non voglio #dall'URL, possiamo rimuoverlo?
Hidayt Rahman

7

Ho avuto lo stesso problema con l'utilizzo di webpack-dev-server. Ho dovuto aggiungere l'opzione devServer al mio webpack.

Soluzione:

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

Kind of voodoo magic: p Per maggiori informazioni, consultare: webpack.github.io/docs/…
Jissay

7

Se stai usando Apache o Nginx come server devi creare un .htaccessRewriteEngine (se non creato prima) e "On"

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

Non hai ricevuto la tua domanda, questo metodo è stato testato sul server Apache e Nginx ( nginx.com )
Rakesh Roy

1
Questo è solo per Apache; Il formato di configurazione di Nginx è totalmente diverso.
Franklin Yu,

5

Il mio server è Apache, quello che ho fatto per correggere 404 durante l'aggiornamento o il deep linking è molto semplice. Basta aggiungere una riga nella configurazione vhost di apache:

ErrorDocument 404 /index.html

In modo che qualsiasi errore 404 venga reindirizzato a index.html, che è ciò che desidera il routing angular2.

L'intero esempio di file 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>

Indipendentemente dal server che stai utilizzando, penso che l'intero punto sia scoprire i modi per configurare il server per reindirizzare 404 al tuo index.html.


4

La configurazione del server non è una soluzione per una SPA, anche quello che penso. Non vuoi ricaricare di nuovo una SPA angolare se arriva una strada sbagliata, vero? Quindi non dipenderò da un percorso del server e reindirizzerò ad un altro percorso, ma sì, lascerò che index.html gestisca tutte le richieste di percorsi angolari del percorso dell'app angolare.

Prova questo invece di percorsi altrimenti o sbagliati. Funziona per me, non ne sono sicuro, ma sembra un lavoro in corso. Sono inciampato da solo di fronte a un problema.

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

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

Tuttavia, ricorda di configurare le cartelle del tuo server e di accedervi nel caso in cui tu abbia HTML o script web che non siano SPA. Altrimenti dovrai affrontare problemi. Per me di fronte a problemi come te era un mix di configurazione del server e superiore.


4

per la correzione rapida angolare 5, modifica app.module.ts e aggiungi {useHash:true}dopo appRoutes.

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

3

Le app angolari sono candidati perfetti per la pubblicazione con un semplice server HTML statico. Non è necessario un motore lato server per comporre dinamicamente le pagine dell'applicazione perché Angular lo fa sul lato client.

Se l'app utilizza il router angolare, è necessario configurare il server per restituire la pagina host dell'applicazione (index.html) quando viene richiesto un file che non ha.

Un'applicazione instradata dovrebbe supportare "deep link". Un deep link è un URL che specifica un percorso a un componente all'interno dell'app. Ad esempio, http://www.example.com/heroes/42 è un collegamento diretto alla pagina dei dettagli dell'eroe che mostra l'eroe con ID: 42.

Non vi sono problemi quando l'utente accede a tale URL dall'interno di un client in esecuzione. Il router angolare interpreta l'URL e indirizza a quella pagina ed eroe.

Ma facendo clic su un collegamento in un'e-mail, immettendolo nella barra degli indirizzi del browser o semplicemente aggiornando il browser nella pagina dei dettagli dell'eroe, tutte queste azioni sono gestite dal browser stesso, al di fuori dell'applicazione in esecuzione. Il browser invia una richiesta diretta al server per quell'URL, ignorando il router.

Un server statico restituisce di routine index.html quando riceve una richiesta per http://www.example.com/ . Ma rifiuta http://www.example.com/heroes/42 e restituisce un errore 404 - Non trovato a meno che non sia invece configurato per restituire index.html

Se questo problema si è verificato in produzione, seguire i passaggi seguenti

1) Aggiungi un file Web.Config nella cartella src della tua applicazione angolare. Inserisci sotto il codice al suo interno.

<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) Aggiungi un riferimento ad esso in angular-cli.json. In angular-cli.json inserire Web.config nel blocco risorse come mostrato di seguito.

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

3) Ora puoi costruire la soluzione per la produzione usando

ng build --prod

Questo creerà una cartella dist. I file all'interno della cartella dist sono pronti per la distribuzione in qualsiasi modalità.


La soluzione migliore può trovare i dettagli da angular : angular.io/guide/deployment#fallback Durante la creazione del file web.config non dimenticare di aggiungere il tag <configuration> </configuration>. Grazie per la risposta Malatesh.
Palash Roy,

3

Puoi usare questa soluzione per una cattiva applicazione, ho usato ejs come motore di visualizzazione:

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

e anche impostato in angular-cli.json

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

funzionerà bene invece di

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

sta creando problemi con get chiamate db e restituendo index.html


1
Funzionava perfettamente nell'ottobre 2017 per l'applicazione stack MEAN.
Mindsect Team,

2

Per quelli di noi che lottano per la vita in IIS: utilizzare il seguente codice PowerShell per risolvere questo problema in base ai documenti Angular 2 ufficiali (che qualcuno ha pubblicato in questo thread? 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

Questo reindirizza il 404 al file /index.html come da suggerimento nei documenti di Angular 2 (link sopra).


2

Puoi provare di seguito. Per me funziona!

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

È possibile migliorare ulteriormente path.substr (2) per suddividere in parametri del router. Sto usando l'angolare 2.4.9


Questo è stato davvero utile per gestire gli aggiornamenti del browser! Per angolare 5, ho dovuto modificarlo un po 'per usare window.location.pathname e confrontare quel valore con i percorsi previsti.
Wallace Howery,

2

Ho appena aggiunto .htaccess in root.

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

qui aggiungo solo il punto '.' (directory principale) in /index.html a ./index.html
assicurandosi che il file index.html nel percorso di base sia il percorso della directory principale e impostato nella build del progetto.


1

Volevo preservare il percorso URL delle sottopagine in modalità HTML5 senza un reindirizzamento all'indice e nessuna delle soluzioni là fuori mi ha detto come fare, quindi è così che l'ho realizzato:

Crea semplici directory virtuali in IIS per tutti i tuoi percorsi e indirizzali alla radice dell'app.

Avvolgi il tuo server system.web nel tuo Web.config.xml con questo tag di posizione, altrimenti otterrai errori duplicati caricando Web.config una seconda volta con la directory virtuale:

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

1

Ho controllato in 2 semi angolari come funziona.

È possibile utilizzare express-history-api-fallback per reindirizzare automaticamente quando viene ricaricata una pagina.

Penso che sia il modo più elegante per risolvere questo problema IMO.


1

Se si desidera utilizzare PathLocationStrategy:

  • Configurazione Wildfly:
    • Creare il file undertow-handlers.conf da inserire nel WEB-INF
    • Contenuto: (escludi gli endpoint di riposo!)
      • regex ['(. / overview / ? . ? $)'] e non regex ['(. / endpoint. )'] -> riscrivi ['/ index.html']
      • regex ['(. / deployments / ? . ? $)'] e non regex ['(. / endpoint. )'] -> riscrivi ['/ index.html']

Applicazione a pagina singola con Java EE / Wildfly: configurazione lato server


1

2017-luglio-11: poiché questo è collegato da una domanda che presenta questo problema ma utilizzando Angular 2 con Electron, aggiungerò la mia soluzione qui.

Tutto quello che dovevo fare era rimuovere <base href="./">dal mio index.html ed Electron ha ricominciato a ricaricare la pagina con successo.


1

Aggiungi importazioni:

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

E nel provider NgModule, aggiungi:

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

Nel file index.html principale dell'app, cambia l'href di base in ./index.htmlda/

L'app quando viene distribuita su qualsiasi server fornirà un vero e proprio URL per la pagina a cui è possibile accedere da qualsiasi applicazione esterna.


1

Basta aggiungere .htaccess nella radice 404 risolto mentre si aggiorna la pagina in 4 angache2 angolare.

<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

Penso che stai ricevendo 404 perché stai richiedendo http: // localhost / route che non esiste sul server Tomcat. Poiché Angular 2 utilizza il routing html 5 per impostazione predefinita anziché utilizzare gli hash alla fine dell'URL, l'aggiornamento della pagina sembra una richiesta per un'altra risorsa.

Quando si utilizza il routing angolare su Tomcat, è necessario assicurarsi che il server esegua il mapping di tutti i percorsi nell'app sull'indice.html principale durante l'aggiornamento della pagina. Esistono diversi modi per risolvere questo problema. Qualunque cosa ti piaccia, puoi farlo.

1) Inserisci il codice seguente in web.xml della cartella di distribuzione:

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

2) Puoi anche provare a utilizzare HashLocationStrategy con # nell'URL per i percorsi:

Prova a usare:

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

Invece di:

RouterModule.forRoot (percorsi)

Con HashLocationStrategy i tuoi URL saranno come:

http: // localhost / # / route

3) Tomcat URL Rewrite Valve: riscrivere l'URL utilizzando una configurazione a livello di server per reindirizzare a index.html se la risorsa non viene trovata.

3.1) All'interno della cartella META-INF creare un file context.xml e copiare il contesto sottostante al suo interno.

<? xml version='1.0' encoding='utf-8'?>
<Context>
  <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>

3.2) All'interno di WEB-INF, creare il file rewrite.config (questo file contiene la regola per la riscrittura degli URL e utilizzato da Tomcat per la riscrittura degli URL). All'interno di rewrite.config, copia il contenuto seguente:

  RewriteCond %{SERVLET_PATH} !-f
  RewriteRule ^/(.*)$ /index.html [L]

0

Questa non è la risposta giusta ma all'aggiornamento è possibile reindirizzare tutte le chiamate morte alla home page sacrificando la pagina 404 è un trucco temporaneo, basta riprodurre di nuovo il file 404.html

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

0

La migliore soluzione per risolvere il "router-non-funzionante-al-ricaricare-il-browser" è che dovremmo usare spa-fallback. Se si utilizza l'applicazione angular2 con core asp.net, è necessario definirla nella pagina "StartUp.cs". sotto le rotte MVC. Ti allego il codice.

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

0

La risposta è piuttosto complicata. Se si utilizza un vecchio server Apache (o IIS) semplice, si ottiene il problema perché le pagine angolari non esistono per davvero. Sono "calcolati" dalla rotta angolare.

Esistono diversi modi per risolvere il problema. Uno è quello di utilizzare la HashLocationStrategy offerta da Angular. Ma un segno acuto viene aggiunto nell'URL. Ciò è principalmente per la compatibilità con Angular 1 (presumo). Il fatto è che la parte dopo che sharp non fa parte dell'URL (quindi il server risolve la parte prima del segno "#"). Questo può essere perfetto.

Ecco un metodo avanzato (basato sul trucco 404). Presumo che tu abbia una versione "distribuita" della tua applicazione angolare (ng build --prod se usi Angular-CLI) e accedi alle pagine direttamente con il tuo server e PHP è abilitato.

Se il tuo sito Web è basato su pagine (Wordpress per esempio) e hai solo una cartella dedicata ad Angular (nel mio esempio "dist"), puoi fare qualcosa di strano ma, alla fine, semplice. Presumo che tu abbia memorizzato le tue pagine angolari in "/ dist" (con il secondo<BASE HREF="/dist/"> ). Ora usa un reindirizzamento 404 e l'aiuto di PHP.

Nella configurazione di Apache (o nel .htaccessfile della directory dell'applicazione angolare), è necessario aggiungereErrorDocument 404 /404.php

404.php inizierà con il seguente codice:

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

dove $angularè il valore memorizzato nell'HREF della tua angolare index.html.

Il principio è abbastanza semplice, se Apache non trova la pagina, viene effettuato un reindirizzamento 404 allo script PHP. Controlliamo solo se la pagina si trova all'interno della directory dell'applicazione angolare. In tal caso, cariciamo direttamente index.html (senza reindirizzamento): questo è necessario per mantenere invariato l'URL. Modifichiamo anche il codice HTTP da 404 a 200 (semplicemente meglio per i crawler).

Cosa succede se la pagina non esiste nell'applicazione angolare? Bene, usiamo il "catch all" del router angolare (consultare la documentazione del router angolare).

Questo metodo funziona con un'applicazione angolare incorporata all'interno di un sito Web di base (penso che sarà il caso in futuro).

APPUNTI:

  • Cercando di fare lo stesso con mod_redirect (riscrivendo gli URL) non è affatto una buona soluzione perché i file (come gli asset) devono essere caricati davvero, quindi è molto più rischioso che usare semplicemente la soluzione "non trovata".
  • Sto solo reindirizzando usando ErrorDocument 404 /dist/index.htmlfunziona ma Apache sta ancora rispondendo con un codice di errore 404 (che è un male per i crawler).

0

Questa non è una soluzione permanente al problema, ma piuttosto una soluzione alternativa o un hack

Ho avuto questo stesso problema durante la distribuzione della mia app angolare su gh-pages. Prima sono stato accolto con 404 messaggi durante l'aggiornamento delle mie pagine su gh-pages.

Quindi, come sottolineato da @gunter, ho iniziato a utilizzare HashLocationStrategyquale fornito con Angular 2.

Ma questo è venuto con il suo proprio insieme di problemi #nell'url che era davvero brutto ha fatto sembrare l'url così strano https://rahulrsingh09.github.io/AngularConcepts/#/faq.

Ho iniziato a ricercare questo problema e mi sono imbattuto in un blog. Ho provato a provarci e ha funzionato.

Ecco cosa ho fatto come menzionato in quel blog.

Dovrai iniziare aggiungendo un file 404.html al repository gh-pages che contenga un documento HTML vuoto al suo interno, ma il tuo documento deve totalizzare più di 512 byte (spiegato di seguito). Quindi inserisci il seguente markup nell'elemento head della tua pagina 404.html:

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

Questo codice imposta l'URL di entrata tentato su una variabile sull'oggetto sessionStorage standard e reindirizza immediatamente alla pagina index.html del progetto usando un tag meta refresh. Se stai realizzando un sito dell'organizzazione Github, non inserire un nome repository nel testo del sostituto dell'attributo del contenuto, procedi nel seguente modo: content = "0; URL = '/'"

Per acquisire e ripristinare l'URL a cui l'utente si è inizialmente spostato, è necessario aggiungere il seguente tag di script all'inizio della pagina index.html prima che qualsiasi altro JavaScript agisca sullo stato corrente della pagina:

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

Questo bit di JavaScript recupera l'URL che abbiamo memorizzato nella cache di sessionStorage sulla pagina 404.html e sostituisce con esso la voce della cronologia corrente.

Backalleycoder di riferimento Grazie a @Daniel per questa soluzione alternativa.

Ora l'URL sopra cambia in https://rahulrsingh09.github.io/AngularConcepts/faq


0

Ho risolto questo problema (usando il backend Java / Spring) aggiungendo un gestore che corrisponde a tutto ciò che è definito nei miei percorsi angolari, che restituisce index.html invece di un 404. Questo quindi efficacemente (ri) riavvia l'applicazione e carica la pagina corretta. Ho anche un gestore 404 per tutto ciò che non è preso da questo.

@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

Se si utilizza Apache o Nginx come server, è necessario creare un .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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.