Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StaticFileOptions.OnPrepareResponse does not get called for index.html

I'm currently trying to disable the caching for index.html for my Angular SPA with a .NET Core 2.2 backend.

I'm doing this according to this answer by setting an OnPrepareResponse action for my StaticFileOptions.

But the Cache-Control header never gets sent. When I set a breakpoint in the OnPrepareResponse action I break for everyfile except index.html

What am I missing here? How can I actually control the cache for the index.html file?

enter image description here

// I've changed nothing else in the default ASP.NET Core/Angular template
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ...

    var staticFileOptions = new StaticFileOptions
    {
        OnPrepareResponse = context =>
        {
            // Breakpoint for next line hits for following files
            // 1: styles.61d14a95058dbe9da495.css
            // 2: runtime.a66f828dca56eeb90e02.js
            // 3: polyfills.7a0e6866a34e280f49e7.js
            // 4: main.d9791b5a6df420d81994.js
            // 5: favicon.ico
            if (context.File.Name == "index.html")
            {
                context.Context.Response.Headers
                    .Add("Cache-Control", "no-cache, no-store, must-revalidate");
                context.Context.Response.Headers.Add("Pragma", "no-cache");
                context.Context.Response.Headers.Add("Expires", "0");
            }
        }
    };

    app.UseStaticFiles(staticFileOptions);
    app.UseSpaStaticFiles(staticFileOptions);

    // ...
}
like image 872
Staeff Avatar asked Sep 17 '19 08:09

Staeff


People also ask

Where do I point usestaticfiles and usefileserver?

UseStaticFiles and UseFileServer defaults to the file provider pointing at wwwroot. You can provide additional instances of UseStaticFiles and UseFileServer with other file providers to serve files from other locations. For more information, see this GitHub issue.

Are the URLs exposed by usedirectorybrowser and usestaticfiles case-sensitive?

The URLs for content exposed with UseDirectoryBrowser and UseStaticFiles are subject to the case sensitivity and character restrictions of the underlying file system. For example, Windows is case insensitive—macOS and Linux aren't.

When is usestaticfiles called before useauthorization?

Static file authorization The ASP.NET Core templates call UseStaticFiles before calling UseAuthorization. Most apps follow this pattern. When the Static File Middleware is called before the authorization middleware:

Why are static files not being served in IIS?

If the IIS static file handler is enabled and the ASP.NET Core Module is configured incorrectly, static files are served. This happens, for example, if the web.config file isn't deployed. Place code files (including .cs and .cshtml) outside of the app project's web root.


2 Answers

You can use this code to see if it work for you

      app.UseSpaStaticFiles(new StaticFileOptions()
            {
                OnPrepareResponse = ctx =>
                {
                    var headers = ctx.Context.Response.GetTypedHeaders();
                    headers.CacheControl = new CacheControlHeaderValue
                    {
                        Public = true,
                        MaxAge = TimeSpan.FromDays(0)
                    };

                }
            });


     app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";
                spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions()
                {
                    OnPrepareResponse = ctx => {
                        var headers = ctx.Context.Response.GetTypedHeaders();
                        headers.CacheControl = new CacheControlHeaderValue
                        {
                            Public = true,
                            MaxAge = TimeSpan.FromDays(0)
                        };
                    }
                };

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
like image 61
Tony Ngo Avatar answered Oct 16 '22 03:10

Tony Ngo


Another solution I came up with looks like this. I'm not sure I love this solution but at least it works.

app.Use(async (context, next) =>
{
    context.Response.OnStarting(() =>
    {
        var requestPath = context.Request.Path.Value;

        if (requestPath.EndsWith("index.html"))
        {
            context.Response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
            context.Response.Headers.Add("Pragma", "no-cache");
            context.Response.Headers.Add("Expires", "0");
        }

        return Task.FromResult(0);
    });

    await next();
});
like image 32
Staeff Avatar answered Oct 16 '22 04:10

Staeff