ASP.NETCore中的ResponseCache使用详解

ASP.NET Core 中的 ResponseCache 使用详解

在 Web 开发中,缓存是提升系统性能、减少服务器压力的重要手段之一。ASP.NET Core 提供了非常方便的响应缓存机制 —— ResponseCache 特性。本文将结合实际代码,带你全面理解 客户端缓存服务端缓存 的区别与使用方式。


一、什么是 ResponseCache?

ResponseCache 是 ASP.NET Core 中用于控制 HTTP 响应缓存行为的一个特性(Attribute)。它本质上是通过设置 HTTP Header(如 Cache-Control)来告诉客户端或代理服务器如何缓存响应。更详细的可以自己去了解一下 RFC 7234.


二、基础示例

我们先来看一个简单的接口示例:

1
2
3
4
5
6
[HttpGet("TestResponseCache")]
[ResponseCache(Duration = 10)]
public async Task<ApiResponse<string>> TestResponseCacheGetNowTime(string number)
{
return ApiResponse<string>.Ok(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
}

说明:

  • Duration = 10:表示缓存有效期为 10 秒
  • 返回的是当前时间字符串,用于测试缓存是否生效

三、客户端缓存(默认行为)

在你只使用 [ResponseCache] 特性,但没有启用中间件时:

1
2
3
// 注意使用客户端缓存的时候,在DI容器中注册服务和使用中间件这两行代码都是注释了的
//builder.Services.AddResponseCaching();
//app.UseResponseCaching();

此时缓存属于:客户端缓存

表现特点:

  • 第一次请求:正常访问服务器,返回当前时间
    运行截图:

屏幕截图 2026-04-02 160255

  • 10 秒内再次请求(参数不变):
    运行截图:

屏幕截图 2026-04-02 160314

从第二张图的红框圈选的信息中可以看出,响应的数据是从 disk cache 中得来的,也就是磁盘缓存。

  • 所以如果参数不改变的情况下,客户端缓存会

    • 直接从浏览器缓存读取
    • 不会再次访问服务器
  • 如果参数改变:

屏幕截图 2026-04-02 161149

黄框 是参数为 1 时的,这时还是读取的磁盘缓存,但后面改成了 12 也就是 红框 的内容,这时再发出请求,虽然还在缓存有效时间内,但却没有读取磁盘缓存,
而是第二次请求参数为 12 时,才读取的磁盘缓存。所以如果在缓存有效时间内,请求参数改变了,

  • 浏览器认为是不同请求
  • 会重新请求服务器

总结:

客户端缓存是“按 URL 缓存”的(参数不同 = 不同缓存)


四、服务端缓存(ResponseCaching 中间件)

如果你启用以下代码:

1
2
builder.Services.AddResponseCaching(); // 注册服务
app.UseResponseCaching(); // 启用中间件(放在 app.MapControllers 之后),注意如果启用了跨域,记得放在跨域限制中间件的后面

同时在控制器的操作方法上加上了特性[ResponseCache(Duration = 10)]

此时就开启了:服务端缓存

有没有看出什么?客户端缓存和服务端缓存,就只是在 program 中有一点点不同。所以启用服务端缓存,也会启用客户端缓存


表现特点:

  • 10 秒内多次请求(并改变参数):

    • 直接返回服务器缓存结果
    • 控制器方法不会再次执行

即使你传入不同参数,也会返回第一次的结果!

运行截图:

屏幕截图 2026-04-02 164541

嗯?

看到黄框和绿框里面的信息,是不是感觉和你想象的结果不一样,启用了服务端缓存不应该都是读取 disk cache 吗?

为什么改变参数后的第一次请求没有读取 disk cache?

注意刚才说了,如果启用服务端缓存,那么客户端缓存也会被启用。

所以当参数改变的时候,就变成了一个新请求,这时就不被客户端缓存管辖了,

他打到服务端了,但是因为还在服务端缓存的有效时间内,所以服务端是没有再执行一次的,而是直接返回上一次运行后的结果的缓存,

这也是改变参数后,后面的履行者不是 disk cache 的原因。注意看红框中的内容,其实从最初到现在都没有改变。

总结一下:在缓存有效时间内,改变参数时的响应来自服务端缓存,未改变参数时的响应来自客户端缓存。


五、客户端缓存 vs 服务端缓存

对比项 客户端缓存 服务端缓存
是否需要中间件 ❌ 不需要 ✅ 需要
控制方式 [ResponseCache] [ResponseCache] + 中间件
缓存位置 浏览器 服务器
是否区分参数 ✅ 区分 ❌ 不区分
是否执行控制器 ❌ 不执行 ❌ 不执行

六、两者关系

当你启用服务端缓存时:

客户端缓存依然存在,并且同时生效

也就是说:

服务端先决定是否返回缓存 → 客户端再决定是否使用本地缓存


七、如何禁用缓存?

如果你不希望使用缓存,可以在请求中添加 Header:

1
Cache-Control: no-cache

这样可以强制:

  • 浏览器重新请求服务器
  • 跳过缓存机制

八、注意事项

浏览器兼容性

并不是所有浏览器都完全支持缓存策略:

  • 某些浏览器可能忽略缓存头
  • 开发者工具(如 Chrome DevTools)开启 “Disable cache” 时缓存失效

参数影响缓存行为

  • 客户端缓存:参数不同 = 新请求
  • 服务端缓存:参数无效(默认不区分)

如果你希望服务端缓存区分参数,需要更高级配置(如 VaryByQueryKeys)


Swagger 测试注意

在 Swagger 中测试时:

  • 有时不会完全模拟浏览器缓存行为
  • 建议结合浏览器 + F12 Network 面板测试

九、总结

一句话总结:

ResponseCache 是通过 HTTP 头控制缓存行为,而是否真正缓存,取决于客户端或服务端配置。

✔ 只加特性 → 客户端缓存
✔ 加中间件 → 服务端缓存
✔ 两者可同时存在


十、适用场景

推荐使用缓存的场景:

  • 不频繁变化的数据(如配置、公告)
  • 高并发接口(降低服务器压力)
  • 静态数据接口(如时间可接受延迟)

不推荐:

  • 实时数据(如交易、库存)
  • 用户敏感数据(缓存可能导致数据错乱)