ASP.NET Core - Cache problems with SPA route in Web API

mikeesouth

Ok, I'm not really sure what the exact problem with my caching is but I'm leaning towards my SPA route fallback in my WebAPI. Sorry for a rather messy post and I know that cache busting is a hot topic here on SO and on blogs but I just can't find the solution to my problem.

First a short overview of the solution. I'm using webpack to bundle my front end code into more or less one css, one js and a index.html. I'm 100% sure that this index.html references these unique css and js files and that the hashes are unique per build/release. Webpack copies these files into my ASP.NET Core project and the wwwroot directory. In my ASP.NET Core code I setup my MVC routes like this:

app.UseMvc(routes =>
{
  routes.MapRoute("api", "api/{controller=Controller}/{action=Index}/{id?}");
  routes.MapRoute("default", "{*url}", new {controller = "Home", action = "RedirectIndex"});
});

The home controller and index action does this:

public ActionResult RedirectIndex()
{
  return new PhysicalFileResult(Path.Combine(_hostingEnvironment.WebRootPath, "index.html"), new MediaTypeHeaderValue("text/html"));
}

I also use app.UseDefaultFiles(); and app.UseStaticFiles(); in my Startup.cs but no cache control.

This is hosted in a web app on Azure.

When I navigate to my app like so: https://my-app.com/ then the default route kicks in and I get served my index.html. Everything works as expected. Except that I get a cached index.html that references my old js and old css files.

NOTE! I do NOT delete my old js and css files from the Azure hosted site so when the cached index.html references the old files - they get served without problems.

Since the index.html is cached my users get an old version of the js logic but the server is updated so my web api sends updated stuff that the js can't handle - I get crashes. I have to tell my users to ctrl + shift + r to do a hard refresh and then it all works.

And one final piece to the puzzle. When I logout I redirect the users to auth0 (an authentication service) to perform the logout. This service (auth0) then redirects the users back to my site (https://my-app.com/) and guess what - they get the old cached index.html again, even though they just ctrl+shift+r refreshed the very same site a couple of minutes earlier.

I'm so confused by this - is it the browser (Chrome) that performs this cache? Is it my magical SPA route redirect using PhysicalFileResult()? Is it Azure? Should I just rename my index.html each build and reference that unique index.html? (That would be an obvious solution but then my webpack config needs to manipulate my C# server code and that creeps me out)

mikeesouth

After some more investigation I've concluded that it must be the browser that caches by some built-in custom logic when the specified file (index.html) does not have cache control headers. Or maybe it's the Azure web server that adds this?

Chrome indicated status code 304 for the index.html (Not Modified) even though it was modified by a slot swap in Azure. I tried modifying the file with an FTP client and that gave me the new version after a reload and status code 200. But when publishing a new version to the stage slot (with a new index.html) I still received the old version in the stage environment and status code 304. Maybe this is because I stop the site, publish and then start it again (??). And when I swapped my stage slot to my production slot the production index.html was again updated but Chrome said 304 (Not Modified) for the produciton environment after a reload. Ctrl+Shift+R always solves this problems.

Anyway. The problem seems to be fixed by this accepted answer: https://stackoverflow.com/a/38235096

Even if I use the slightly custom PhysicalFileResult() the StaticFilesOptions() kicks in and I get a 200 status code every reload. My index.html is very small so this is perfectly OK solution.

Hope this helps someone else.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Manage two SPA in a single ASP.NET Core 3.1 Web API; One in the root and the other in "admin" route

Implicit grant with ASP.net core 2 web API and SPA

Implement HTTP Cache (ETag) in ASP.NET Core Web API

ASP.NET Core prevent spa-fallback route for api routes

ASP.Net Core Web API custom route not working

Attaching middleware to a specific route in ASP.NET Core Web API?

ASP.NET Core Web API : route by query parameter

Change the default route in Asp.net core Web Api

ASP.NET CORE, Web API: No route matches the supplied values

How to run compiled SPA static files along with ASP.NET Core Web API publish in docker container?

How to properly implement "Google Login" in Asp.Net Core Web Api and a spa (Angular)?

Angular SPA routes on ASP.NET Web API project

ASP.NET Web-api core: Handling client connections problems and find conflicts

Problems combining JWT Bearer Authenticating Web API with Asp.Net Core 2.0

What is the Problems of my Code in Claim base Authorization ASP.NET CORE WEB API?

ASP.Net Core Web API - ResponseCache attribute is not adding "Cache-Control" header to the reponse

Memory cache seems to differ between endpoints in Asp.Net Core Web Api

Inheriting route attributes in ASP.NET Core Web API 3.1+

Can't map route to action, ASP.NET Core Web API

Is it possible to bind Route Value to a Custom Attribute's Property in ASP.NET Core Web API?

How to allow a double '/' in a route of an ASP.NET Core Web Api action?

ASP.Net web api Vs .Net core web api

CACHE MANIFEST – in ASP.NET CORE 2 Angular 5.x SPA Template

How to control browser cache expiration when serving SPA from wwwroot in ASP.NET Core App

Determine Static files based off route or domain in ASP.NET Core for SPA

ASP.Net Core routes with Web API

ASP.NET Core Web API Authentication

debugging the asp.net core web API

Multiple MemoryCache in ASp .Net Core Web API