.NET Core ResponseCache 浏览器缓存


.NET Core ResponseCache 浏览器缓存

一、前言

1、最近一直在看项目性能优化方式,俗话说的好项目优化第一步那当然是添加缓存,我们的项目之所以卡的和鬼一样,要么就是你的代码循环查询数据库(这个之前在我们的项目中经常出现,现在慢慢在修正)或者代码做了很多不该做的事情。这个时候就可以引入我们的缓存了。(只要你的代码不是写的特别差,比如之前实习的我)。

2、缓存主要分为两种 客户端(浏览器缓存)、服务端缓存。当我们的数据不需要及时返回的时候,可以考虑将页面缓存到客户的浏览器中进行保存,在一定的时间内访问直接读取浏览器缓存的信息。我们通过设置HTTP的响应头 Cache-Control 来完成页面存储到浏览器缓存中如下所示:

.NET Core ResponseCache 浏览器缓存

二、客户端(浏览器缓存)

1、在老的版本的MVC里面,有一种可以缓存视图的特性(OutputCache),可以保持同一个参数的请求,在N段时间内,直接从mvc的缓存中读取,不去走视图的逻辑。

C# 全选
//老版本的.NET 做法
[OutputCache(Duration =20)]//设置过期时间为20秒  
public ActionResult ExampleCacheAction()  
{  
	var  time=DateTime.Now.ToString("yyyy年MM月dd日 HH时mm分ss秒");  
	ViewBag.time= time;  
	return View();  
}  

2、在.Net core 中就没有(OutputCache)了,使用的是(ResponseCache)特性。官方文档上称:响应缓存可减少客户端或代理对 web 服务器的请求数。 响应缓存还可减少量工作的 web 服务器执行程序生成响应。 响应缓存由标头,指定你希望客户端、 代理和缓存响应的中间件如何控制。

C# 全选
/*
 Duration 代表缓存持续时间(秒)至少1秒
 VaryByHeader 设置vary 请求头信息使用vary头有利于内容服务的动态多样性。例如,使用Vary: User-Agent头,缓存服务器需要通过UA判断是否使用缓存的页面。
 Location 缓存位置
		  None 报头设置为“no-cache”不使用缓存
		  Client 只缓存在客户端。设置“Cache-control”标题为“private”。
		  Any 缓存在代理和客户端。设置“Cache-control”标题为“public”。
 NoStore   缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。如果设置为False Duration必须大于0
 VaryByQueryKeys 可以按照相同页面,不同的参数进行相应的存储
 CacheProfileName 设置缓存配置文件的值,可以通过设置不同的缓存参数
*/
[ResponseCache(Duration = 50, VaryByQueryKeys = new string[] { "q","name" })]
public IActionResult Index(int q,string name)
{
	return View(DateTime.Now);
}

3、通过运行我们可以看到,浏览器多了一个cache-control:public,max-age=50 它的意思是public缓存在代理和客户端。max-age=50代表缓存的时间50秒。

.NET Core ResponseCache 浏览器缓存

4、还有一种简单粗暴的实现方式,因为我们知道添加了这个特性只是在响应请求头中添加了一个cache-control:public,max-age=50,那么我们可以也可以直接在请求响应中设置这个请求头就完事了,效果都是一样的。

C# 全选
public IActionResult Index()
{
    //直接一,简单粗暴,不要拼写错了就好~~
    Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.CacheControl] = "public, max-age=600";
    
    //直接二,略微优雅点
    //Response.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
    //{
    //    Public = true,
    //    MaxAge = TimeSpan.FromSeconds(600)
    //};

    return View();
}

5、有时候为了统一管理缓存配置,我们可以将缓存配置提前写到配置中,使用名字进行调用。[ResponseCache(CacheProfileName ="test")],在Startup中注入视图的时候写入。

C# 全选
//设置一些缓存策略
services.AddControllersWithViews(options =>
{
	options.CacheProfiles.Add("default", new CacheProfile
	{
		Duration = 60
	});

	options.CacheProfiles.Add("test", new CacheProfile
	{
		Duration = 30,
		Location=ResponseCacheLocation.Client
	});
});

.NET Core ResponseCache 浏览器缓存

6、[ResponseCache] 参数

  • Duration 设置缓存的存储时间(以秒为单位)。设置“Cache-control”中的“max-age”。
  • Location
    • Any 缓存在代理和客户端。设置“Cache-control”标题为“public”。
    • Client 只缓存在客户端。设置“Cache-control”标题为“private”。
    • None 每次有请求发出时,缓存会将请求发到服务器 ,服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。 报头设置为“no-cache”。
  • NoStore 缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。
  • VaryByHeader 使用vary头有利于内容服务的动态多样性。例如,使用Vary: User-Agent头,缓存服务器需要通过UA判断是否使用缓存的页面。
  • VaryByQueryKeys 可以按照相同页面,不同的参数进行相应的存储
  • CacheProfileName 设置缓存配置文件的值,可以通过设置不同的缓存参数

三、服务端缓存

1、ResponseCache也可以设置服务端缓存,将我们返回的数据存储在服务端中在一定的时间内返回存储的数据,这里我先引入一个案例,有时候我们需要传递不同的参数进行缓存。

  • 案例:当我们访问的数据带分页参数的时候我们怎么做呢?VaryByQueryKeys前面我们讲了这个,可以根据不同的参数进行缓存,那么我们现在使用看看 。
  • 结果:当我们运行的时候,发现报错了,报错的意思大致是说我们没有使用中间件,但是为什么我这个缓存要使用到中间件呢?其实是因为要区分,我们请求的参数,然后会将我们的数据进行缓存起来,就是实现了服务端缓存。这里的我们就要使用微软提供的中间件了。

.NET Core ResponseCache 浏览器缓存

.NET Core ResponseCache 浏览器缓存

2、我们主要是在Startup中注入services.AddResponseCaching();和app.UseResponseCaching();中间件。服务端缓存可以缓存页面数据和API数据,同时如果我们服务端存在数据,也就是缓存命中的情况下,会直接从缓存中取,不会再进入我们的方法。

C# 全选
public void ConfigureServices(IServiceCollection services)
{
	  services.AddResponseCaching(options =>
	{
		options.UseCaseSensitivePaths = false;
		options.MaximumBodySize = 1024;
		options.SizeLimit = 100 * 1024*1024;
	});
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
	app.UseResponseCaching();
}

服务端缓存配置如下,当我们配置添加了中间件和注入缓存之后,就可以使用VaryByQueryKeys了。当我们访问一次之后就会将结果缓存到我们的客户端缓存中,和服务端缓存各一份。当我们使用同一个浏览器访问的时候访问的就是客户端缓存信息,当我们切换浏览器访问的时候也不会请求我们的方法,会先进入到我们的中间件中查看是否存在服务端缓存,如果存在就是直接拿缓存进行返回,如果没有就会请求方法返回,然后再将结果进行缓存。

属性描述
MaximumBodySize响应正文的最大可缓存大小(以字节为单位)。 默认值为 64 * 1024 * 1024 (64 MB)。
SizeLimit响应缓存中间件的大小限制(以字节为单位)。 默认值为 100 * 1024 * 1024 (100 MB)。
UseCaseSensitivePaths确定是否将响应缓存在区分大小写的路径上。 默认值是 false。

3、对于一些常年不变或比较少变的js,css等静态文件,也可以把它们缓存起来,避免让它们总是发起请求到服务器,而且这些静态文件可以缓存更长的时间!如果已经使用了CDN,这一小节的内容就可以暂且忽略掉了。。。对于静态文件,.NET Core有一个单独的StaticFiles中间件,如果想要对它做一些处理,同样需要在管道中进行注册。UseStaticFiles有几个重载方法,这里用的是带StaticFileOptions参数的那个方法。因为StaticFileOptions里面有一个OnPrepareResponse可以让我们修改响应头,以达到HTTP缓存的效果。

C# 全选
app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = context =>
    {
        context.Context.Response.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue
        { 
            Public = true,
            //for 1 year
            MaxAge = System.TimeSpan.FromDays(365)
        };
    }
});

四、使用前置条件

  • 请求必须导致服务器响应,状态代码为200(正常)。
  • 请求方法必须为 GET 或 HEAD。
  • 在 Startup.Configure中,响应缓存中间件必须置于需要缓存的中间件之前。
  • Authorization 标头不得存在。
  • Cache-Control 标头参数必须是有效的,并且响应必须标记为 “public” 且未标记为 “private”。
  • 如果 Cache-Control 标头不存在,则 Pragma: no-cache 标头不得存在,因为 Cache-Control 标头在存在时将覆盖 Pragma 标头。
  • Set-Cookie 标头不得存在。
  • Vary 标头参数必须有效且不等于 *。
  • Content-Length 标头值(如果已设置)必须与响应正文的大小匹配。
  • 不使用 IHttpSendFileFeature。
  • Expires 标头和 max-age 和 s-maxage 缓存指令指定的响应不能过时。
  • 响应缓冲必须成功。 响应的大小必须小于配置的或默认 SizeLimit。 响应的正文大小必须小于配置的或默认的 MaximumBodySize。
  • “请求” 或 “响应” 标头字段中不得存在 “no-store” 指令。
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
管理员
上一篇:.NET Core 深入理解依赖注入 services.AddTransient,services.AddScoped,services.AddSingleton
下一篇:asp.net mvc Action直接返回图片不被浏览器缓存
评论列表

发表评论

评论内容
昵称:
关联文章

.NET Core ResponseCache 浏览器缓存
.NET Core 缓存使用之 MemoryCache
asp.net mvc Action直接返回图片不被浏览器缓存
使用.NET 6开发TodoList应用(22)——实现缓存
解决VUE发布后因为浏览器缓存造成页面没更新的问题
ASP.NET Core官网教程,资料查找
ASP.NET Core开发者学习路线图
C#使用默认浏览器打开URL
Python Selenium使用火狐浏览器驱动
ASP.NET Core 使用 LESS
C# ASP.NET Core开发学生信息管理系统(二)
.NET Core 项目windows server中部署
.NET Core 项目 DbProviderFactories.GetFactoryClasses()返回空
【推荐】Razor文件编译 ASP.NET Core
.NET Core,.NET5 固定输出目录,不要版本目录
.NET Core集成JWT授权验证
AP.NET Core获得注入管理器
.NET Core 自定义中间件 Middleware
.NET Core定时任务(控制台程序)
.NET5 ASP.NET Core 添加API限流

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码