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

时间:2016-11-01 21:42:13

标签: asp.net-core asp.net-core-mvc asp.net-core-1.0 coreclr

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

  

响应缓存是指在HTTP上指定与缓存相关的标头   ASP.NET Core MVC操作所做的响应。这些标头指定了如何   您希望客户端和中间(代理)计算机缓存响应   某些要求(如果有的话)。这可以减少数量   从未来请求客户端或代理向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,但没有运气。每次我在地址栏中输入网址或点击刷新时,客户端(即浏览器或邮递员)都会调用行动方法。

3 个答案:

答案 0 :(得分: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?

答案 1 :(得分:2)

长话短说,使用如下所示的ResponseCache属性足以使基于过期的客户端缓存在全新的默认dotnet核心项目(包括async方法)中运行:

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

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

如果无论发送请求 ,则说明您有一些中间件或服务器配置都覆盖了响应头,或者您的客户端忽略了缓存指令。在上面的屏幕截图中,客户端忽略了缓存,因为缓存控制标头就在那里。

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

  • 在使用没有证书(或无效证书)的HTTPS时,Chrome prevents进行任何类型的缓存,这对于本地开发来说通常很常见,因此请确保在测试缓存或信任自签名时使用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()中间件混淆,因为这是用于服务器端缓存(默认情况下使用使用中间件时的内存缓存)。客户端缓存不需要中间件,该属性本身就足够了。

答案 2 :(得分:-1)

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

  1. ResponseCache不等于OutputCache。

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

  3. 现在如果你想要像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