ResponseCache属性不会在客户端缓存数据

问题描述 投票:15回答:3

在ASP.NET Core应用程序中,我有一个返回一些数据的action方法。我想在客户端缓存这些数据。所以基于documentation here我可以在动作方法上使用ResponseCache属性。此属性在响应中添加Cache-Control标头

响应缓存是指在ASP.NET Core MVC操作所做的HTTP响应上指定与缓存相关的标头。这些标头指定了您希望客户端和中间(代理)计算机如何缓存对某些请求的响应(如果有的话)。这可以减少客户端或代理对Web服务器的请求数,因为可以从客户端或代理的缓存提供对相同操作的未来请求。

响应缓存不会缓存Web服务器上的响应。它与输出缓存不同,后者会在早期版本的ASP.NET和ASP.NET MVC中缓存服务器内存中的响应。

所以这就是我的动作方法的样子

public class LookupController : Controller
{
    [HttpGet]
    [ResponseCache(Duration = 120)]
    public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
    {
        return _domain.GetStateProvinces();
    }
}

然后我使用浏览器调用方法http://localhost:40004/lookup/getstateprovinces这是请求和响应标头

enter image description here

请注意,响应标头符合预期的Cache-Control: public,max-age-120。但是,如果使用F5刷新页面(120秒之前),则GetStateProvince操作方法中的调试器断点总是会命中。这意味着它不会破坏客户端的数据。

我还需要做些什么来启用客户端缓存吗?

更新我尝试过使用IE,Chrome和POSTMAN但没有运气。每次我在地址栏中输入网址或点击刷新时,客户端(即浏览器或邮递员)都会调用操作方法。

asp.net-core asp.net-core-mvc asp.net-core-1.0 coreclr
3个回答
12
投票

实际上,ResponseCache属性按预期工作。 不同之处在于,如果您浏览网站页面(案例1),或使用后退和前进按钮(而不是刷新页面时),则会缓存响应。

作为案例1的一个例子,我有以下内容:

正如您将在文章Response Caching in ASP.Net Core 1.1中看到的那样,陈述如下:

在浏览器会话期间,浏览网站内的多个页面或使用后退和前进按钮访问页面,内容将从本地浏览器缓存(如果未过期)提供。 但是当页面通过F5刷新时,请求将转到服务器,页面内容将刷新。您可以使用F5通过刷新联系页面进行验证。 因此,当您点击F5时,响应缓存到期值无法发挥作用来提供内容。您应该看到200个联系请求响应。

参考文献: [1]。 ASP.NET Core Response Caching Sample [2]。 ResponseCache attribute sample [3]:How to control web page caching, across all browsers?


2
投票

简而言之,使用如下所示的ResponseCache属性足以使基于过期的客户端缓存在全新的默认dotnet核心项目(包括async方法)中工作:

[HttpGet]
[ResponseCache(Duration = 120)]
public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
{
    return _domain.GetStateProvinces();
}

这在上面的屏幕截图中正常工作,因为Cache-Control: public,max-age=120在那里可见。在大多数情况下,浏览器不会在到期之前(即接下来的120秒或2分钟)发送后续请求,但这是浏览器(或其他客户端)的决定。

如果无论发送请求,您要么有一些中间件或服务器配置覆盖您的响应头,要么您的客户端忽略缓存指令。在上面的屏幕截图中,客户端忽略缓存,因为缓存控制头是存在的。

忽略客户端缓存并发送请求的常见情况:

  • Chrome prevents在使用没有证书的HTTPS时使用任何类型的缓存(或者证书无效,这通常用于本地开发,因此请确保在测试缓存时使用HTTP,或者信任自签名证书)
  • 大多数浏览器开发工具在打开时默认禁用缓存,这可以被禁用 浏览器通常会发送额外的标题,Chrome发送Cache-Control: no-cache
  • 直接刷新(即Ctrl + F5)将指示大多数浏览器不使用缓存并在不考虑年龄的情况下发出请求 浏览器通常会发送额外的标头,Chrome会发送Cache-Control: max-age=0(这在您的屏幕截图中可见)
  • 邮递员发送Cache-Control: no-cache标头,使其绕过本地缓存,导致请求被发送;您可以从设置对话框中禁用它,在这种情况下,将不再使用上述客户端缓存配置发送请求

此时我们超出了基于到期的客户端缓存,服务器将以这种或那种方式接收请求,并发生另一层缓存:您可以使服务器响应304 Not Modified代码(然后再次使用客户端以任何方式解释它或使用服务器端缓存并使用完整内容进行响应。或者您不能使用任何后续缓存,只需在服务器上再次执行整个请求处理。


注意:ResponseCache属性不应与启动配置中的services.AddResponseCaching()app.UseResponseCaching()中间件混淆,因为这是用于服务器端缓存(默认情况下使用内存缓存时,使用中间件)。客户端缓存不需要中间件工作,属性本身就足够了。


-1
投票

首先,我想澄清一些事情,我相信你已经知道了。

  1. ResponseCache不等于OutputCache。
  2. ResponseCache是​​根据我的思维集标题,但它不会在服务器端缓存任何内容。

现在,如果您想要像OutputCache一样缓存,那么您可能必须使用刚刚发布的预览版本1.1。

ASP.net核心1.1预览版

https://blogs.msdn.microsoft.com/webdev/2016/10/25/announcing-asp-net-core-1-1-preview-1/

他们引入了新的响应缓存中间件。响应缓存中间件

在这里可以看到它的演示。 https://github.com/aspnet/ResponseCaching/blob/dev/samples/ResponseCachingSample/Startup.cs

© www.soinside.com 2019 - 2024. All rights reserved.