10

I have an angular 2 website that is based on the Angular 2 "Tour of Heroes" Quick Start.

It works fine when running locally. After fixing things to no longer use local node_modules (per the deployment steps from the quick start) and deploying to the Azure web app the app works fine if I start at the root URL ("/"). However, using Angular routing the URL changes (to "/home" for example) and if I do an F5 refresh of that URL, the app fails to load. When I do that I get a 404 with:

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

I tried using a web.config as described here but that did not help. It definitely seems like it is an IIS issue where it tries to serve up a page instead of starting with index.html. My routes are defined in Angular and they work locally.

Kirk Liemohn
  • 7,733
  • 9
  • 46
  • 57
  • I am not very clear about the scenario of *"the app works fine except when I try to load the app from a URL other than "/" "*. As Angular 2 is a SPA framework, normally, there is only one entry point (e.g. `index.html`) for the app. – Aaron Chen Feb 20 '17 at 08:42
  • I just updated my explanation. Hopefully it is clearer now. – Kirk Liemohn Feb 20 '17 at 12:39
  • 1
    Have you seen [this post](http://stackoverflow.com/questions/38823595/angular2-page-refresh-404ing-when-hosted-in-azure)? As the answer point out, you'd need to setup `HashLocationStrategy` to fix this. – Aaron Chen Feb 20 '17 at 15:14
  • Thanks for pointing that out @AaronChen-MSFT. I may resort to the HashLocationStrategy. I'm seeing others mention using rewrite rules in the web.config (as I already referenced, but also as the post you link to mentions). I'm not giving up on web.config yet as it seems like the appropriate approach, but I'm missing something if it is. – Kirk Liemohn Feb 20 '17 at 18:32

4 Answers4

21

Can you try this web.config file

<configuration>
    <system.webServer>
         <rewrite>
            <rules>
              <rule name="AngularJS 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>
          <caching enabled="true" enableKernelCache="true">
              <profiles>
                  <add extension=".js" policy="DisableCache" kernelCachePolicy="DisableCache" />
              </profiles>
          </caching>
    </system.webServer>
</configuration>
bipin patel
  • 2,061
  • 1
  • 13
  • 22
0

The web.config solution did not work for me at all. After a day or so of digging around and tearing my hair out, I came across this post which resolved the issue for me. It appears to be doing something similar in that for a 404 that isn't related to any /api/ request, serve up the root page, whereupon the Angular routing should kick in and serve up the correct view. As per the link above, in Startup.cs at the beginning of the void Configure() method, I inserted the following code:

    app.Use(async (HttpContext context, Func<Task> next) =>
    {
      await next.Invoke();

      if (context.Response.StatusCode == 404 && !context.Request.Path.Value.Contains("/api"))
      {
          context.Request.Path = new PathString("/");
          await next.Invoke();
      }
   });

The only thing I've done differently is set the root url to '/' (my root razor page that's hosting the Angular app) instead of index.html in the example. The versions I'm using are .NET Core 2.2 and Angular 7.2.1.

santos
  • 434
  • 3
  • 6
0

Add this file in src/assets/routes.json

 {
  "routes": [
    {
      "route": "/*",
      "serve": "/index.html",
      "statusCode": 200
    }
  ]
}

let me know if it workes ?

Anzar Alim
  • 47
  • 8
0

Not sure if it's too late, but here is what you need

  1. app-routing.module.ts add useHash: true
  2. modify your navigation to use #
  3. compile your application: ng build --configuration production
  4. upload your files to your static site

enter image description here

enter image description here

enter image description here

Sebastian Castaldi
  • 8,580
  • 3
  • 32
  • 24