本文介绍了ResponseCache 在网络核心 3.1 中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了解 .NET Core 3.1 中的响应缓存.但它没有如我所愿.我在 Chrome devtool 中查看了网络,它显示了带有 cache-control: no-cache, no-store 的响应头.

我还发现响应标头在 Actionfilter 中带有 HeaderCacheControl{public,max-age=100}.这是我期望的值,但浏览器中的实际响应标头是 no-cache.

启动类:

public void ConfigureServices(IServiceCollection services){services.AddResponseCaching(options=>{options.SizeLimit = 1024;options.MaximumBodySize = 1024 * 1024 * 100;options.UseCaseSensitivePaths = false;});}公共无效配置(IApplicationBuilder 应用程序,IWebHostEnvironment 环境){如果 (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseCookiePolicy();app.UseStaticFiles();app.UseRouting();app.UseAuthentication();app.UseAuthorization();app.UseResponseCaching();app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(名称:默认",模式:{controller=Home}/{action=Index}/{id?}");});}

控制器:

[ResponseCache(Duration = 100, NoStore = false)]公共 IActionResult 索引(){返回视图();}
解决方案

这是正常行为,无论是否从磁盘缓存中检索页面,都会影响多种因素.

我将尝试列出用户请求页面以及页面是否被缓存的常见场景.

  1. AddResponseCachingUseResponseCaching 控制服务器端缓存,而 ResponseCacheAttribute 通过设置适当的标头来控制客户端缓存.

我喜欢控制客户端缓存的方式是设置如下配置文件:

services.AddControllersWithViews(options =>{options.CacheProfiles.Add(缓存", new CacheProfile(){持续时间 = 120,位置 = ResponseCacheLocation.Any,VaryByHeader = cookie"});options.CacheProfiles.Add("NoCaching", new CacheProfile(){NoStore = 真,位置 = ResponseCacheLocation.None});})

你像这样使用它:

[ResponseCache(CacheProfileName = "Caching")]
  1. Chrome 会在没有证书的情况下使用 HTTPS 或证书无效时阻止任何类型的缓存(在开发中,系统会提示您信任开发证书以便通过 HTTPS 工作)

  2. 浏览器在开发工具打开时禁用缓存,它们通常会发送一个Cache-Control: no-cache

  3. 在 chrome 上点击重新加载 (Ctrl + F5) 也会禁用缓存并发送一个 Cache-Control: max-age=0 标头以及您的请求,服务器会遵守该请求.>

  4. 如果您想测试缓存是否真的有效,请执行以下操作:

    1. 打开您的 Chrome 开发工具并取消选中 Disable cache 复选框(如果已选中).

    2. 像往常一样请求您的页面.

    3. 不要尝试通过页面中引用同一页面的锚标记请求同一页面(您应该看到该页面是从磁盘缓存中检索的)(如果满足以下条件).

    4. 您也可以从另一个页面导航到您的(缓存激活)页面,如果它被缓存,它将从磁盘缓存中拉出(如果满足以下条件).

  5. 带有表单和/或任何类型的授权的页面不会被缓存.包含防伪令牌的页面将与 Cache-ControlPragma 标头一起发送到 no-cache.您可以在 MSDN.

  6. 还有一些工具,如 Fiddler 和 Postman,默认发送 no-cache 标头.

I tried to learn about Response Caching in .NET Core 3.1. But it didn't work as I wished. I viewed the network in Chrome devtool, and it showed the response header with cache-control: no-cache, no-store.

I also found that Response header was with HeaderCacheControl{public,max-age=100} in Actionfilter. It was the value I expected, but the actual response header in browser is no-cache.

Startup class:

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

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseCookiePolicy();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseResponseCaching();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Controller:

[ResponseCache(Duration = 100, NoStore = false)]
public IActionResult Index()
{

    return View();
}
解决方案

This is normal behaviour, there are multiple factors that plays on if the page is retrieved from disk cache or not.

I'll try to list common scenarios on which a user would request a page and if it's cached or not.

  1. AddResponseCaching and UseResponseCaching controls server side caching while ResponseCacheAttribute controls client side caching via setting the appropriate headers.

The way i like to control client side caching is by setting profiles like the following:

services.AddControllersWithViews(options =>
{
    options.CacheProfiles.Add("Caching", new CacheProfile()
    {
        Duration = 120,
        Location = ResponseCacheLocation.Any,
        VaryByHeader = "cookie"
    });
    options.CacheProfiles.Add("NoCaching", new CacheProfile()
    {
        NoStore = true,
        Location = ResponseCacheLocation.None
    });

})

and you use it like this:

[ResponseCache(CacheProfileName = "Caching")]
  1. Chrome prevents any kind of caching when using HTTPS without a certificate or when the certificate is invalid (in development you are prompted to trust the development cert in order to work over HTTPS)

  2. Browsers disable caching when dev tools are open, they usually send a Cache-Control: no-cache

  3. Hitting reload on chrome (Ctrl + F5) also disables cache and sends a Cache-Control: max-age=0 header with your request which is respected by the server.

  4. If you wish to test your cache if it's really working, do the following:

    1. Open your Chrome dev tools and uncheck the Disable cache checkbox if it's checked.

    2. Request your page like you normally would.

    3. Not try to request the same page via an anchor tag in the page that reference the same page (you should see that the page is retrieved from disk cache) (if the conditions below are respected).

    4. Also you can navigate to your (cache activated) page from another page, if it's cached it will be pulled from the disk cache (if the conditions below are respected).

  5. Pages with Forms and/or any kind of Authorization won't be cached. Pages with Antiforgery token included will be sent with Cache-Control and Pragma headers to no-cache. You can see all the conditions for caching on MSDN.

  6. Also some tools like Fiddler and Postman send no-cache header by default.

这篇关于ResponseCache 在网络核心 3.1 中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 23:08