Angular Error 2: 404 occurs when updating through a browser

I am new to Angular 2. I have saved a one-page application on my server in a folder named "myapp". I changed the base url to http://example.com/myapp/ `.

My project has two pages. Therefore, I implement Angular 2 routing. I set the default page as login. When I type http://example.com/myapp/ in my browser, it automatically redirects to http://example.com/myapp/login . But if I refresh this page, I get 404 error saying that http://example.com/myapp/login not found.

But if I run my project using the Lite server, everything works. In this case, the base URL in index.html will be "/" . How to fix it?

+156
angular angular2-routing
Feb 09 '16 at 6:04
source share
7 answers

In fact, it’s normal that you get a 404 error when updating the application, since the actual address is updated in the browser (and without the # / hashbang approach). By default, HTML5 history is used for reuse in Angular2.

To fix the 404 error, you need to update the server so that it serves the index.html file for each route you specify.

If you want to switch to the HashBang approach, you need to use this 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} ]); 

In this case, when you refresh the page, it will be displayed again (but you will have # in your address).

This link can also help you: when I update my site, I get 404. This is with Angular2 and firebase .

Hope this helps you, Thierry

+118
Feb 09 '16 at 6:09
source share

Update for Angular 2 Final Version

In app.module.ts:

  • Add import:

     import { HashLocationStrategy, LocationStrategy } from '@angular/common'; 
  • And in the NgModule provider, add:

     {provide: LocationStrategy, useClass: HashLocationStrategy} 

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

Use RouterModule.forRoot with the argument {useHash: true}.

Example: (from corner documents )

 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 { } 
+226
Aug 23 '16 at 13:51 on
source share

For people (like me) who really want PathLocationStrategy (i.e. html5Mode) instead of HashLocationStrategy , see How to: set up a server to work with html5Mode from a third-party wiki:

When you have html5Mode enabled, the # character will no longer be used in your URLs. The # character is useful because it does not require server-side configuration. Without # , the URL looks much better, but it also requires server side rewriting.

Here I will copy only three examples from the wiki, in case the wiki gets lost. Other examples can be found by searching for the keyword "URL rewrite" (for example, this answer is for 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 for rewriting module

Nginx

 server { server_name my-app; root /path/to/app; location / { try_files $uri $uri/ /index.html; } } 

Documentation for 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> 
+99
Nov 27 '16 at 19:44
source share

I had the same problem. Angular application runs on a Windows server.

I solved this problem by creating a web.config file in the root directory.

 <?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
Dec 18 '16 at 15:14
source share

Perhaps you can do this by registering your root using the RouterModule. You can pass a second object with the property "useHash: true", as shown below:

 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
Sep 27 '16 at 7:27
source share

For people reading this using Angular 2 rc4 or later, a LocationStrategy appears, moved from the router to the regular one. You will have to import it from there.

Also notice the braces around the “provide” line.

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} ]); 
+6
Jul 14 '16 at 10:05
source share

If you use Angular 2 through ASP.NET Core 1 in Visual Studio 2015, you may find this solution from Jürgen Gutsch useful. He describes this in a blog post . It was the best solution for me. Put the C # code below in your Startup.cs public void Configure () just before 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
Oct 25 '16 at 6:36
source share



All Articles