Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache busting index.html in a .Net Core Angular 5 website

I am creating a website using .Net core and angular 5. I created the project using the latest .Net core angular template (using dotnet new angular with .Net core 2.1 installed).

This project uses the angular cli to build/package and applies a hash onto the bundled js and css files:

enter image description here

However after publishing my site to an azure app service I found that when I browsed to the site I would see the old version until I manually refreshed with F5 (Ctrl-F5 wasn't necessary). This seems to be because although the js/css files wont be cached, the index.html page which contains the references to these files will be served from the cache.

When I press F5 to reload the website the index.html (home below) is requested from the site (304 in this case as it hasn't changed, if it has it will get the latest):

enter image description here

However when I initially load the page (via a bookmark or typing in the address etc) the page is directly served from cache:

enter image description here

Is this expected behaviour? Why is it different loading the page for the first time vs pressing F5? And can I/should I prevent this caching?

like image 889
QTom Avatar asked Jun 14 '18 16:06

QTom


2 Answers

Here's what I ended up with after combining a bunch of answers. My goal was to never cache index.html. While I was in there, and since Angular nicely cache-busts the js and css files, I had it cache all other assets for a year.

Just make sure you're using a cache-busting mechanism for assets, like images, that you're managing outside of Angular.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  // ...
  app.UseStaticFiles();

  if (env.IsDevelopment())
  {
    // no caching
    app.UseSpaStaticFiles();
  }
  else
  {
    app.UseSpaStaticFiles(new StaticFileOptions
    {
      OnPrepareResponse = context =>
      {
        context.Context.Response.Headers.Add("Cache-Control", "max-age=31536000");
        context.Context.Response.Headers.Add("Expires", "31536000");
      }
    });
  }

  // ...

  app.UseSpa(spa =>
  {
    spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
    {
      OnPrepareResponse = context =>
      {
        // never cache index.html
        if (context.File.Name == "index.html")
        {
          context.Context.Response.Headers.Add("Cache-Control", "no-cache, no-store");
          context.Context.Response.Headers.Add("Expires", "-1");
        }
      }
    };
  });
}

Other StackOverflow Answers: Disable Caching in .Net Core | Cache for a year

like image 59
JackMorrissey Avatar answered Oct 06 '22 00:10

JackMorrissey


Not a neat or perfect solution but this seems to have worked and might get people on the right track:

In Configure() in Startup.cs I added this

app.Use(async (c, next) =>
{
    if (c.Request.Path == "/")
    {
        c.Response.Headers.Add("Cache-Control", "no-store,no-cache");
        c.Response.Headers.Add("Pragma", "no-cache");
    }
    await next();
});

Since adding this I haven't been able to reproduce my issue.

like image 43
QTom Avatar answered Oct 05 '22 23:10

QTom