不会为 index.html 调用 StaticFileOptions.OnPrepareResponse

Sta*_*eff 5 c# node.js typescript asp.net-core angular

我目前正在尝试index.html使用 .NET Core 2.2 后端为我的 Angular SPA禁用缓存。

我根据这个答案通过OnPrepareResponse为我的StaticFileOptions.

但是Cache-Control标头永远不会被发送。当我在 OnPrepareResponse 操作中设置断点时,我会为每个文件中断,除了 index.html

我在这里缺少什么?我怎样才能真正控制index.html文件的缓存?

在此处输入图片说明

// 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);

    // ...
}
Run Code Online (Sandbox Code Playgroud)

Ton*_*Ngo 5

您可以使用此代码查看它是否适合您

      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");
                }
            });
Run Code Online (Sandbox Code Playgroud)

  • @Staeff:我相信@TonyNgo 的回答是正确的。OP代码不起作用的原因是“index.html”是由“app.UseSpa()”而不是“app.UseSpaStatic()”处理的。只有其他 `css`/`js`/... 静态文件由 `app.UseSpaStatic()` 提供服务。 (4认同)
  • 我认为 UseSpa 下的部分是正确的,但在 `UseSpaStaticFiles` 内的部分中,您应该删除 `OnPrepareResponse` 处理程序。这样,您将仅禁用默认文件路径的缓存,并且将为其他静态文件启用缓存。 (2认同)

Sta*_*eff 5

我想出的另一个解决方案如下所示。我不确定我是否喜欢这个解决方案,但至少它有效。

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();
});
Run Code Online (Sandbox Code Playgroud)