asp.net core 系列之Reponse caching 之 Response Caching Middleware(4)

这篇文章介绍 Response Caching Middleware .

Response Caching Middleware in ASP.NET Core

通过在ASP.NET Core应用中 配置 Response Caching Middleware ,决定什么时候 response 是可以缓存,存储response,和从缓存中提供response 服务。

一.Package

需要引用的 Microsoft.AspNetCore.App, 或者添加Microsoft.AspNetCore.ResponseCaching

二.Configuration

Startup.ConfigureServices中,添加中间件到service collection.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddResponseCaching();
    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

配置应用通过UseResponseCaching扩展方法使用中间件,它增加中间件到请求处理管道

这个示例应用增加了一个Cache-Control头到response,应用缓存可缓存的responses长达10秒。

示例发送一个Vary头来配置中间件,提供一个缓存的response,只有当随后请求的Accept-Encoding头匹配原始请求的Accept-Encoding.

在随后的代码例子中,CacheControlHeaderValueHeaderNames要求一个有用状态,对于MIcrosoft.Net.Http.Headers命名空间。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseResponseCaching();

    app.Use(async (context, next) =>
    {
        // For GetTypedHeaders, add: using Microsoft.AspNetCore.Http;
        context.Response.GetTypedHeaders().CacheControl = 
            new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(10)
            };
        context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] = 
            new string[] { "Accept-Encoding" };

        await next();
    });

    app.UseMvc();
}

Response Caching Middleware仅仅缓存返回的状态码为200的server responses。

任何其他的responses,包括error pages(错误页),都会被中间件忽视。

警告:包含认证客户端的Responses必须被标记为不可缓存来防止中间件存储和提供那些响应。

三.Options

中间件提供了三个options(选项)来控制resonse caching.

下面例子中配置中间件为:

  • 缓存响应小于等于1024字节
  • 存储响应时区分路径大小写(例如, /page1/Page1被分开存储)
services.AddResponseCaching(options =>
{
    options.UseCaseSensitivePaths = true;
    options.MaximumBodySize = 1024;
});

四.VaryByQueryKeys

当使用MVC/Web API控制器或者Razor Pages page models,这些ResponseCache属性会指定必要的参数,来为response caching设置合适的头.

唯一要求中间件的ResponseCache属性是VaryByQueryKeys, VaryByQueryKeys不会回应一个真实的HTTP头。

当不使用ResponseCache属性时,response caching 可以随着VaryByQueryKeys的功能变化。

直接使用来自HttpContextIFeatureCollectionResponseCachingFeature :

var responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>();
if (responseCachingFeature != null)
{
    responseCachingFeature.VaryByQueryKeys = new[] { "MyKey" };
}

在VaryByQueryKeys中,使用一个等于 * 的单独的值,会随着所有request query parameters 而改变cache的值。

五.HTTP headers used by Response Caching Middleware

Response caching被中间件使用HTTP headers来配置,下面是一些HTTP头

 

六.Caching respects request Cache-Control directives

 中间件遵守HTTP 1.1 Caching secification(specification:说明书)的规则。

这些规则要求cache拥有一个被client发送的有效的Cache-Control头,

在说明书下,一个client可以发送一个带no-cache头值的请求,并且强制服务器为每个请求生成一个新的响应。

目前,开发者无法控制缓存行为,当使用中间件时;因为中间件依附于官方的缓存说明书。

七.Troubleshooting(发现并解决故障)

如果缓存行为没按预期进行,确认 响应是可缓存的和缓存提供的功能。

检查请求进入时的头部和响应出去时的头部。允许记录日志来帮助调试。

当测试和troubleshooting缓存行为时,浏览器可能会以不合需的方式设置请求头并影响到缓存。

例如,浏览器可能设置Cache-Control头为no-cache或者max-age=0当刷新页面时。下面的工具可以明确的设置请求头并且对于测试缓存很受欢迎:

Conditions for caching (缓存的限制)

  • 请求必须导致返回一个带200状态码的服务器响应
  • 请求方式必须是GETHEAD
  • Startup.Configure,Response Caching Middleware必须放在要求压缩的中间件之前。
  • Authorization头必须不存在
  • Cache-Control头参数必须是有效的,并且响应必须被标记为public 并且不能是private
  • The Pragma: no-cache头不能出现,如果Cache-Control头没有出现,因为当Cache-Control出现的时候,Cache-Control头会重写Pragma
  • Set-Cookie头必须不能出现
  • Vary头参数必须是有效的,并且不等于*
  • Content-Length头的值必须匹配the size of the response body. (如果设置的话)
  • IHttpSendFileFeature没有被使用
  • Response必须不是陈旧的,当被Expires头和max-ages-maxage缓存指令 指定的时候
  • Response buffering(响应缓冲)必须是成功的,并且响应的大小必须小于配置的或者默认的SizeLimit.
  • Response必须是可缓存的根据RFC 7234说明书。例如,no-store指令不能存在于请求或响应头字段中。

 

posted @ 2019-06-28 00:22  Vincent-yuan  阅读(...)  评论(...编辑  收藏