ASP.NET Core ResponseCache cache operation

Original: ASP.NET cache Core operating the ResponseCache

Foreword

This chapter introduces the client-side caching will introduce the browser cache and the server cache, use the browser cache will reduce the number of web requests to the server, and can improve performance and avoid duplication of operational waste.

ASP.NET Core for HTTP caching divided into two types:

  • The client (browser cache)
  • Service-side caching

Client-side caching

By providing the HTTP response header Cache-Control to complete the page stored in the browser cache as follows:

Client-side caching schematic

In fact, if the client cache only needs to be set ResponseCache characteristics can see the following snippet


[ResponseCache(Duration = 100,Location = ResponseCacheLocation.Client)]
public IActionResult Index()
{
      return View();
}

ResponseCacheAttribute can be used:

  • Razor page handler (s) - Characteristics handler method can not be applied.
  • MVC controller (s).
  • MVC operation (method) - Method level characteristics of the coverage level characteristics specified settings.

[ResponseCache] parameters

  • Duration set the cache storage time (in seconds). Settings "Cache-control" in the "max-age".
  • Location
    • Any caching proxies and clients. Set "Cache-control" titled "public".
    • Client only cached on the client. Set "Cache-control" entitled "private".
    • None every time when the request is made, the request will be sent to the cache server, the cache server will verify whether the request described in the expired, if not expired (Note: The actual return is 304), the cache is used only locally cached copy. Header is set to "no-cache".
  • NoStore cache must not store any content on client requests and server responses. Each time a request initiated by the client will download the complete contents of the response.
  • VaryByHeader 使用vary头有利于内容服务的动态多样性。例如,使用Vary: User-Agent头,缓存服务器需要通过UA判断是否使用缓存的页面。
  • VaryByQueryKeys 可以按照相同页面,不同的参数进行相应的存储
  • CacheProfileName 设置缓存配置文件的值,可以通过设置不同的缓存参数

CacheProfileName使用请看如下代码片段


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews(options =>
            {
                options.CacheProfiles.Add("default", new CacheProfile
                {
                    Duration = 60
                });

                options.CacheProfiles.Add("test", new CacheProfile
                {
                    Duration = 30
                });
            });
        }

上述代码我们设置好了两份不一样的配置,那么我们就可以通过下面代码片段进行使用了


    [ResponseCache(CacheProfileName = "default")]
    public IActionResult Index()
    {
         return View();
   }

服务端缓存

服务端缓存可以缓存页面数据和API数据,同时如果我们服务端存在数据,也就是缓存命中的情况下,会直接从缓存中取,不会再进入我们的方法。

        public void ConfigureServices(IServiceCollection services)
        {
              services.AddResponseCaching(options =>
            {
                options.UseCaseSensitivePaths = false;
                options.MaximumBodySize = 1024;
                options.SizeLimit = 100 * 1024*1024;
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseResponseCaching();
        }
        

服务端缓存配置如下

属性 描述
MaximumBodySize 响应正文的最大可缓存大小(以字节为单位)。 默认值为 64 * 1024 * 1024 (64 MB)。
SizeLimit 响应缓存中间件的大小限制(以字节为单位)。 默认值为 100 * 1024 * 1024 (100 MB)。
UseCaseSensitivePaths 确定是否将响应缓存在区分大小写的路径上。 默认值是 false。
        [ResponseCache(Duration = 30, VaryByQueryKeys = new[] { "q" })]
        public IActionResult Index(int q)
        {
            _logger.LogWarning($"我是一个路径:{HttpContext.Request.Host}");
            return View(model:DateTime.Now.ToString());
        }

VaryByQueryKeys

使用 MVC/web API 控制器或 Razor Pages 页面模型时, [ResponseCache]属性指定为响应缓存设置适当的标头所需的参数。 严格需要中间件的 [ResponseCache] 属性的唯一参数 VaryByQueryKeys,这与实际 HTTP 标头不对应。 有关详细信息,请参阅 响应缓存在 ASP.NET Core。
如果不使用 [ResponseCache] 属性,响应缓存可能会与 VaryByQueryKeys不同。
我们再看看如上代码效果

ResponseCache中间件使用的 HTTP 标头

响应头 描述
Authorization 如果标头存在,则不会缓存。
Cache-Control 中间件仅考虑用 public 缓存指令标记的缓存响应。
Pragma 请求中的 Pragma: no-cache 标头将产生与 Cache-Control: no-cache相同的效果。 如果存在此标头,则由 Cache-Control 标头中的相关指令重写。 考虑向后兼容 HTTP/1.0。
Set-Cookie 如果标头存在,则不会缓存响应。 请求处理管道中设置一个或多个 cookie 的任何中间件会阻止响应缓存中间件缓存响应(例如,基于 cookie 的 TempData 提供程序)。
Vary Vary 标头用于根据另一个标头改变缓存的响应。 例如,通过编码来缓存响应,包括 Vary: Accept-Encoding 响应头,该响应头将缓存标头为 Accept-Encoding: gzip 和 Accept-Encoding: text/plain 的请求的响应。 永远不会存储响应头值为 * 的响应。
Expires 除非被其他 Cache-Control 标头重写,否则不会存储或检索此响应头过时的响应。
If-None-Match 如果值不为 *,响应的 ETag 与提供的任何值都不匹配,则将从缓存中提供完整响应。 否则,将提供304(未修改)响应。
If-Modified-Since 如果 If-None-Match 标头不存在,则在缓存的响应日期比提供的值更新时,将从缓存中提供完整响应。 否则,将提供304-未修改响应
Date 从缓存提供时,如果未在原始响应中提供,则中间件会设置 Date 标头。
Content-Length 从缓存提供时,如果未在原始响应中提供,则中间件会设置 Content-Length 标头。
Age 忽略原始响应中发送的 Age 标头。 中间件在为缓存的响应提供服务时计算一个新值。

缓存条件

  • 请求必须导致服务器响应,状态代码为200(正常)。
  • 请求方法必须为 GET 或 HEAD。
  • 在 Startup.Configure中,响应缓存中间件必须置于需要缓存的中间件之前。
  • Authorization 标头不得存在。
  • Cache-Control 标头参数必须是有效的,并且响应必须标记为 "public" 且未标记为 "private"。
  • 如果 Cache-Control 标头不存在,则 Pragma: no-cache 标头不得存在,因为 Cache-Control 标头在存在时将覆盖 Pragma 标头。
  • Set-Cookie 标头不得存在。
  • Vary 标头参数必须有效且不等于 *。
  • Content-Length 标头值(如果已设置)必须与响应正文的大小匹配。
  • 不使用 IHttpSendFileFeature。
  • Expires 标头和 max-age 和 s-maxage 缓存指令指定的响应不能过时。
  • 响应缓冲必须成功。 响应的大小必须小于配置的或默认 SizeLimit。 响应的正文大小必须小于配置的或默认的 MaximumBodySize。
  • "Request" or "response" can not be present in the header field "no-store" instruction.

Reference

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching_FAQ

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-3.1

https://github.com/hueifeng/BlogSample/tree/master/src/ResponseCachingDemo

Author: @ Feng Hui
Source: https://www.cnblogs.com/yyfh/archive/2020/02/25/12361255.html

This article belongs to the author and blog Park total, welcome to reprint, but without the author's consent declared by this section must be preserved, and the original link is given in the apparent position of the article page

Guess you like

Origin www.cnblogs.com/lonelyxmas/p/12363978.html