我想在asp.net core 2.0中使用服务器端响应缓存(输出缓存)并找到关于Response Caching Middleware的内容,并希望尝试使用全新的asp.core mvc项目 .
以下是上面链接的描述,这让我觉得这可以像输出缓存一样使用 .
中间件确定响应何时可缓存,存储响应以及从缓存提供响应 .
这是我的startup.cs的样子 .
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCaching();
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCaching();
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
这是HomeController.cs
[ResponseCache(Duration = 60)]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
return View();
}
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
_Layout.cshtml文件底部还有一个时间戳,所以我可以告诉页面何时呈现,如下所示 .
<p>© 2018 - ResponseCachingMiddleware - @DateTime.UtcNow</p>
Cache-Control Headers 看起来很好,这是我加载页面时在 Headers 中得到的,但时间戳每秒刷新一次 .
Cache-Control:public,max-age=60
我从MS文档中理解的是响应缓存中间件是服务器端缓存机制,它负责缓存响应,而Response Caching似乎只是一个操作缓存响应头的过滤器 .
无法判断我的理解或代码是否有问题,我想抱怨自从我开始使用ASP.Net Core进行原型设计以来,我经常会这样 . 也许你也可以建议更好的资源作为一个侧面话题 .
我已经在ASP.NET Core 2.0 - Http Response Caching Middleware - Nothing cached之前查看了这篇文章
也检查了这一点,但似乎唯一的区别是我正在使用mvc . https://github.com/aspnet/ResponseCaching/blob/dev/samples/ResponseCachingSample/Startup.cs
谢谢
编辑:我在输出窗口中看到下面的消息,除了我已经检查过响应缓存中间件的几个地方之外,在谷歌上找不到任何关于它的信息 .
Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware:信息:无法为此请求缓存响应 .
注意:我希望我可以创建#response -caching-middleware标签 . 不确定#responsecache是否相关 .
3 回答
我最近也有同样的困惑 .
ASP.Net Core的ResponseCaching确实提供了客户端缓存(通过HTTP响应头)和服务器端(通过内存缓存的中间件,如果响应在缓存中,它会使其他中间件短路) . 服务器端部分读取HTTP响应缓存头以确定它是否应该执行服务器端缓存(类似于ISP或CDN可能执行的操作) .
不幸的是,调试服务器端的ResponseCaching很棘手,因为它有奇怪的规则并且没有足够的日志记录 . 在我的情况下,我删除了微软的源代码,逐步完成它并找到我的代码问题 .
您在输出窗口“无法为此请求缓存响应”中找到的注释是一个线索 .
服务器端缓存请求有两个部分 . 服务器必须在第一次请求URL时填充缓存 . 它将在第二次请求时提供缓存版本 . 注意错误消息何时显示,如果是在第一个或第二个请求上 . 这将告诉您它是否无法存储在缓存中或无法从缓存中检索 .
存储和检索的规则都在此源代码文件中:https://github.com/aspnet/ResponseCaching/blob/3bf5f6a1ce69b65c998d6f5c739822a9bed4a67e/src/Microsoft.AspNetCore.ResponseCaching/Internal/ResponseCachingPolicyProvider.cs
你的“Cache-Control:public,max-age = 60” Headers 应该符合这些规则 .
我的猜测是你实际上有它工作,但不知道如何正确测试它 . 本期中提到了一个反直觉的ResponseCaching部分:https://github.com/aspnet/Home/issues/2607本质上,如果浏览器发送无缓存或无存储头(当您按CTRL F5或打开调试器工具时),ASP.Net Core 's ResponseCaching will honor the browser' s请求并重新生成响应 .
因此,要测试您的代码是否正常工作,您可能已加载了启动缓存的页面,然后按CTRL F5强制刷新浏览器,并且您希望服务器端使用缓存条目进行响应,而不是运行WebAPI代码 . 但是,它尊重了无缓存请求标头并绕过了缓存(并在输出日志中写入了该消息) .
测试这种方法的方法是在请求之间清除浏览器缓存(或切换到隐身),而不是使用CTRL F5 .
另外,尊重no-cache / no-store请求标头可能是一个糟糕的设计选择,因为ASP.Net Core的ResponseCache很可能被拥有响应的服务器使用,而不是像CDN /那样的中间缓存ISP . 我已经扩展了基本的ResponseCache,并选择了禁用这些头文件(以及将缓存序列化为磁盘,而不是仅限内存) . 它是默认缓存的简单替代品 .
你可以在这里找到我的扩展名:https://github.com/speige/AspNetCore.ResponseCaching.Extensions https://www.nuget.org/packages/AspNetCore.ResponseCaching.Extensions
还有一些其他的问题与ResponseCaching有关,你可能已经在你发布的博客网址中看到了这些问题 . 使用set-cookie的经过身份验证的请求和响应将不会被缓存 . 只缓存使用GET或HEAD方法的请求 . 如果QueryString不同,它将创建一个新的缓存条目 . 此外,如果请求的某些条件与先前缓存的不同,通常您会想要一个“Vary”标头来阻止缓存请求(例如:user-agent,accept-encoding等) . 最后,如果一个中间件处理一个请求,它将在以后的中间件短路 . 确保你的app.UseResponseCaching()在app.UseMVC()之前注册
我遇到了同样的问题,我正要把它拉过来,我设置
app.UseResponseCaching();
以及services.AddResponseCaching();
并在我的操作之上添加ResponseCache
,就像微软官方Docs中所说的那样,尽管设置了cache-controll
Headers 正确地响应从服务器返回但仍未在服务器端缓存 .在这个问题上经过几个小时的出汗后,我想出了问题出现的原因以及为什么没有任何缓存在服务器上 .
默认情况下,浏览器会为请求将
cache-controll
值设置为max-age=0
(如果请求不是由后向或前向引起的),即使您在响应中正确设置了cache-controller
,也可以在您的操作(或控制器)之上添加ResponseCache
属性,因为cache-controller
发送了请求设置为max-age=0
,服务器无法缓存响应,我认为这必须添加到 Response Caching 限制列表中无论如何,您可以通过在调用
app.UseResponseCaching();
之前添加几行代码来覆盖浏览器默认行为,另一方面,您需要在调用app.UseResponseCaching();
之前添加自定义中间件来修改请求cache-control
标头值 .看下面的代码,为我工作也希望为你工作
为确保ResponseCaching按预期工作,您也可以使用邮递员,但必须在设置中将 'Send no-cache Header' 设置为 off ,请参见下图
如果
Cache-Control
标头正在通过,则它可以从该角度查看所有服务器的所有内容 . 客户端最终决定是否实际缓存资源 . 发送 Headers 不会强制客户端执行任何操作;事实上,服务器通常不能强迫客户端做任何事情 .