ASP.NET Core错误响应携带Cache-Control头的原因及禁止缓存方法
解决方案
你遇到的问题核心是[ResponseCache]特性会无视响应状态码统一添加Cache-Control头,虽然ASP.NET Core自带的响应缓存中间件不会缓存非200响应,但客户端或CDN等代理会根据该头缓存错误响应,可通过以下方式解决:
方案1:全局Result过滤器(推荐,无需修改现有业务代码)
新增全局过滤器,所有请求返回前自动判断状态码,非200响应直接覆盖缓存头:
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Http; public class DisableNon200ResponseCacheFilter : IAsyncResultFilter { public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) { var resultContext = await next(); if (resultContext.HttpContext.Response.StatusCode != StatusCodes.Status200OK) { var responseHeaders = resultContext.HttpContext.Response.Headers; responseHeaders.CacheControl = "no-cache, no-store, must-revalidate"; responseHeaders.Pragma = "no-cache"; responseHeaders.Expires = "0"; } } }
修改Startup.cs中控制器注册逻辑,把过滤器加入全局配置:
services.AddControllers(options => { options.Filters.Add<DisableNon200ResponseCacheFilter>(); });
方案2:自定义中间件(适合需要更灵活控制缓存逻辑的场景)
如果需要在更底层处理缓存逻辑,可以用中间件实现,优先级比过滤器更高:
using Microsoft.AspNetCore.Http; public class Non200ResponseCacheMiddleware { private readonly RequestDelegate _next; public Non200ResponseCacheMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { // 响应头发送前触发判断 context.Response.OnStarting(() => { if (context.Response.StatusCode != StatusCodes.Status200OK) { context.Response.Headers.CacheControl = "no-cache, no-store, must-revalidate"; context.Response.Headers.Pragma = "no-cache"; context.Response.Headers.Expires = "0"; } return Task.CompletedTask; }); await _next(context); } }
修改Startup.cs的中间件注册顺序,注意要放在UseResponseCaching之前:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseCors(); // 新增自定义中间件 app.UseMiddleware<Non200ResponseCacheMiddleware>(); app.UseResponseCaching(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
两种方案都不会影响200正常响应的缓存规则,仅对非200的错误响应生效,从根源上避免客户端/代理缓存错误内容。
内容的提问来源于stack exchange,提问作者Jordan Walker
相关产品推荐
相关产品推荐

