如何在 ASP.NET Core 中缓存静态文件?

Col*_*tie 9 caching static-files vue.js asp.net-core

我似乎无法在 ASP.NET Core 2.2 中启用静态文件缓存。我有以下内容Configure

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
  if (env.IsDevelopment()) {
    app.UseDeveloperExceptionPage();
    app.UseCors(...);
  }
  else {
    app.UseHsts();
  }

  app.UseHttpsRedirection();
  app.UseAuthentication();
  app.UseSignalR(routes => { routes.MapHub<NotifyHub>("/..."); });

  app.UseResponseCompression();
  app.UseStaticFiles();
  app.UseSpaStaticFiles(new StaticFileOptions() {
    OnPrepareResponse = (ctx) => {
      ctx.Context.Response.Headers[HeaderNames.CacheControl] = "public, max-age=31557600"; // cache for 1 year
    }
  });
  app.UseMvc();

  app.UseSpa(spa => {
    spa.Options.SourcePath = "ClientApp";
    if (env.IsDevelopment()) {
      spa.UseVueCli(npmScript: "serve", port: 8080);
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用 chrome 在 HTTPS 上审核生产站点时,我不断收到“使用高效缓存策略提供静态资产”的消息:

审核截图

在网络选项卡中没有提到标题中的缓存,当我按 F5 时,似乎所有内容都来自磁盘缓存。但是,如果审计显示它不是,我怎么能确定我的缓存设置有效?

网络标签截图

小智 9

我不知道UseSpaStaticFiles是什么,但您可以在UseStaticFiles 中添加缓存选项。您错过了设置Expires标头。

// Use static files
app.UseStaticFiles(new StaticFileOptions {
    OnPrepareResponse = ctx =>
    {
        // Cache static files for 30 days
        ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=2592000");
        ctx.Context.Response.Headers.Append("Expires", DateTime.UtcNow.AddDays(30).ToString("R", CultureInfo.InvariantCulture));
    }
});
Run Code Online (Sandbox Code Playgroud)

请注意,当您对静态文件进行更改时,您还需要一种使缓存无效的方法。

我写了一篇关于这个的博客文章:在 ASP.NET Core 中缩小和缓存静态文件


HMZ*_*HMZ 7

这适用于 ASP.NET Core 2.2 到 3.1:

我知道这有点类似于 Fredrik 的回答,但您不必输入文字字符串来获取缓存控制标头

app.UseStaticFiles(new StaticFileOptions()
{
    HttpsCompression = Microsoft.AspNetCore.Http.Features.HttpsCompressionMode.Compress,               
    OnPrepareResponse = (context) =>
    {
        var headers = context.Context.Response.GetTypedHeaders();
        headers.CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue
        {
            Public = true,
            MaxAge = TimeSpan.FromDays(30)
        };
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 注意:不需要设置`HttpsCompressionMode`! (5认同)
  • @Ali如果响应同时包含“Expires”标头和“max-age”指令,则“max-age”优先。参考:13.2.4 过期计算 - https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html max-age 指令优先于 Expires,因此如果响应中存在 max-age,则计算很简单: (3认同)