ASP.NET Core中的Http緩存使用
Http響應(yīng)緩存可減少客戶端或代理對(duì)web服務(wù)器發(fā)出的請(qǐng)求數(shù)。響應(yīng)緩存還減少了web服務(wù)器生成響應(yīng)所需的工作量。響應(yīng)緩存由Http請(qǐng)求中的header控制。
而ASP.NET Core對(duì)其都有相應(yīng)的實(shí)現(xiàn),并不需要了解里面的工作細(xì)節(jié),即可對(duì)其進(jìn)行良好的控制。
了解Http緩存
Http協(xié)議中定義了許多緩存,但總體可以分為強(qiáng)緩存和協(xié)商緩存兩類。

強(qiáng)緩存
強(qiáng)緩存是指緩存命中時(shí),客戶端不會(huì)向服務(wù)器發(fā)請(qǐng)求,瀏覽器F12能看到響應(yīng)狀態(tài)碼為200,size為from cache,它的實(shí)現(xiàn)有以下幾種方式:
Expires - 絕對(duì)時(shí)間
示例:Expires:Thu,31 Dec 2037 23:59:59 GMT,就表示緩存有效期至2037年12月31日,在這之前瀏覽器都不會(huì)向服務(wù)器發(fā)請(qǐng)求了(除非按F5/Ctrl+F5刷新)。
Cache-Control - 相對(duì)時(shí)間/更多控制
絕對(duì)時(shí)間是一個(gè)絕對(duì)時(shí)間,因?yàn)橛?jì)算時(shí)不方便;而且服務(wù)端是依據(jù)服務(wù)器的時(shí)間來返回,但客戶端卻需要依據(jù)客戶的時(shí)間來判斷,因此也容易失去控制。
Cache-Control有以下選項(xiàng)(可以多選):
- max-age: 指定一個(gè)時(shí)間長度,在這個(gè)時(shí)間段內(nèi)緩存是有效的,單位是秒(s)。例如設(shè)置Cache-Control:max-age=31536000,也就是說緩存有效期為31536000/24/60/60=365天。
- s-maxage: 同max-age,覆蓋max-age、Expires,但僅適用于共享緩存,在私有緩存中被忽略。
- public: 表明響應(yīng)可以被任何對(duì)象(發(fā)送請(qǐng)求的客戶端、代理服務(wù)器等等)緩存。
- private: 表明響應(yīng)只能被單個(gè)用戶(可能是操作系統(tǒng)用戶、瀏覽器用戶)緩存,是非共享的,不能被代理服務(wù)器緩存。
- no-cache: 強(qiáng)制所有緩存了該響應(yīng)的用戶,在使用已緩存的數(shù)據(jù)前,發(fā)送帶驗(yàn)證器的請(qǐng)求到服務(wù)器。(不是字面意思上的不緩存)
- no-store: 禁止緩存,每次請(qǐng)求都要向服務(wù)器重新獲取數(shù)據(jù)。
- must-revalidate: 指定如果頁面是過期的,則去服務(wù)器進(jìn)行獲取。(意思是瀏覽器在某些情況下,緩存失效后仍可使用老緩存,加了這個(gè)頭,失效后就必須驗(yàn)證,并不是字面上有沒有過期都驗(yàn)證)
其中最有意思的要數(shù)no-cache和must-revalidate了,因?yàn)樗鼈兊谋憩F(xiàn)都不是字面意義。
no-cache并不是字面上的不緩存,而是會(huì)一直服務(wù)端驗(yàn)證(真實(shí)意義很像字面上的must-revalidate)。
而must-revalidate是只是為了給瀏覽器強(qiáng)調(diào),緩存過期后,千萬要遵守約定重新驗(yàn)證。
協(xié)商緩存
協(xié)商緩存是指緩存命中時(shí),服務(wù)器返回Http狀態(tài)碼為304但無內(nèi)容(Body),沒命中時(shí)返回200有內(nèi)容。
在要精細(xì)控制時(shí),協(xié)商緩存比強(qiáng)緩存更有用,它有Last-Modified和ETag兩種。
Last-Modified/If-Modify-Since(對(duì)比修改時(shí)間)
示例:
服務(wù)器:Last-Modified: Sat, 27 Jun 2015 16:48:38 GMT
客戶端:If-Modified-Since: Sat, 27 Jun 2015 16:48:38 GMT
ETag/If-None-Match(對(duì)比校驗(yàn)碼)
服務(wù)器:ETag: W/"0a0b8e05663d11:0"
客戶端:If-None-Match: W/"0a0b8e05663d11:0"
清緩存要點(diǎn)
- 按
F5刷新時(shí),強(qiáng)緩存失效 - 按
Ctrl+F5刷新時(shí) 強(qiáng)緩存和協(xié)商緩存都失效
ASP.NET Core的Http緩存
ASP.NET Core中提供了ResponseCacheAttribute來實(shí)現(xiàn)緩存,它的定義如下:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ResponseCacheAttribute : Attribute, IFilterFactory, IFilterMetadata, IOrderedFilter
{
public ResponseCacheAttribute();
public string CacheProfileName { get; set; }
public int Duration { get; set; }
public bool IsReusable { get; }
public ResponseCacheLocation Location { get; set; }
public bool NoStore { get; set; }
public int Order { get; set; }
public string VaryByHeader { get; set; }
public string[] VaryByQueryKeys { get; set; }
}
其中,ResponseCacheLocation定義了緩存的位置,是重點(diǎn):
// Determines the value for the "Cache-control" header in the response.
public enum ResponseCacheLocation
{
// Cached in both proxies and client. Sets "Cache-control" header to "public".
Any = 0,
// Cached only in the client. Sets "Cache-control" header to "private".
Client = 1,
// "Cache-control" and "Pragma" headers are set to "no-cache".
None = 2
}
注意看源文件中的注釋,Any表示Cache-Control: public,Client表示Cache-Control: private,None表示Cache-Control: no-cache。
注意ResponseCacheLocation并沒有定義將緩存放到服務(wù)器的選項(xiàng)。
其中Duration表示緩存時(shí)間,單位為秒,它將翻譯為max-age。
另外可以通過VaryByHeader和VaryByQueryKeys來配置緩存要不要通過header和query string來變化,其中VaryByHeader是通過Http協(xié)議中的Vary頭來實(shí)現(xiàn)的,VaryByQueryKeys必須通過Middleware來實(shí)現(xiàn)。
不要誤會(huì),所有ResponseCacheAttribute的屬性配置都不會(huì)在服務(wù)端緩存你的響應(yīng)數(shù)據(jù)(雖然你可能有這種錯(cuò)覺),它和輸出緩存不同,它沒有狀態(tài),只用來做客戶端強(qiáng)緩存。
如果不想緩存,則設(shè)置NoStore = true,它會(huì)設(shè)置cache-control: no-store,我們知道no-store的真實(shí)意思是不緩存。一般還會(huì)同時(shí)設(shè)置Location = ResponseCacheLocation.None,它會(huì)設(shè)置cache-control: no-cache(真實(shí)意思是表示一定會(huì)驗(yàn)證)。
注意單獨(dú)設(shè)置Location = ResponseCacheLocation.None而不設(shè)置NoStore并不會(huì)有任何效果。
示例1
這是一個(gè)很典型的使用示例:
public class HomeController : Controller
{
[ResponseCache(Duration = 3600, Location = ResponseCacheLocation.Client)]
public IActionResult Data()
{
return Json(DateTime.Now);
}
}
我定義了3600秒的緩存,并且cache-control應(yīng)該為private,生成的Http緩存頭可以通過如下C#代碼來驗(yàn)證:
using var http = new HttpClient();
var resp1 = await http.GetAsync("https://localhost:55555/home/data");
Console.WriteLine(resp1.Headers.CacheControl.ToString());
Console.WriteLine(await resp1.Content.ReadAsStringAsync());
輸入結(jié)果如下:
max-age=3600, private
"2020-03-07T21:35:01.5843686+08:00"
另外,ResponseCacheAttribute也可以定義在Controller級(jí)別上,表示整個(gè)Controller都受到緩存的影響。
CacheProfileName示例
另外,如果需要共用緩存配置,可以使用CacheProfileName,將緩存提前定義好,之后直接傳入這個(gè)定義名即可使用:
.ConfigureServices(s =>
{
s.AddControllers(o =>
{
o.CacheProfiles.Add("3500", new CacheProfile
{
Duration = 3500,
Location = ResponseCacheLocation.Client,
});
});
});
這樣我就定義了一個(gè)名為3500的緩存,稍后在Controller中我只需傳入CacheProfileName = 3500即可:
public class HomeController : Controller
{
[ResponseCache(CacheProfileName = "3500")]
public IActionResult Data()
{
return Json(DateTime.Now);
}
}
總結(jié)
Http緩存分為強(qiáng)緩存和協(xié)商緩存,ASP.NET Core提供了便利的ResponseCacheAttribute實(shí)現(xiàn)了強(qiáng)緩存,還能通過Profile來批量配置多個(gè)緩存點(diǎn)。
但ASP.NET MVC并沒有提供協(xié)商緩存實(shí)現(xiàn),因?yàn)檫@些多半和業(yè)務(wù)邏輯相關(guān),需要自己寫代碼。靜態(tài)文件是特例,Microsoft.AspNetCore.StaticFiles中提供有,因?yàn)殪o態(tài)文件的邏輯很清晰。
ASP.NET中的OutputCacheAttribute在ASP.NET Core中不復(fù)存在,取而代之的是app/services.AddResponseCaching(),這些和Http協(xié)議不相關(guān)。
有機(jī)會(huì)我會(huì)具體聊聊這些緩存。
到此這篇關(guān)于ASP.NET Core中的Http緩存使用的文章就介紹到這了,更多相關(guān)ASP.NET Core Http緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
visual studio 2015+opencv2.4.13配置教程
這篇文章主要為大家詳細(xì)介紹了visual studio 2015+opencv2.4.13配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
.net core2.0下使用Identity改用dapper存儲(chǔ)數(shù)據(jù)(實(shí)例講解)
下面小編就為大家分享一篇.net core2.0下使用Identity改用dapper存儲(chǔ)數(shù)據(jù)的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-11-11
ASP.NET MVC @Helper輔助方法和@functons自定義函數(shù)的使用方法
本文主要介紹ASP.NET MVC中使用@Helper和@functons自定義一些代碼片段,方便視圖調(diào)用,從而達(dá)到減少重復(fù)代碼,快速開發(fā)的目的,希望對(duì)大家有所幫助。2016-04-04
輕量級(jí)ORM框架Dapper應(yīng)用之實(shí)現(xiàn)In操作
這篇文章介紹了使用Dapper實(shí)現(xiàn)In操作的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
詳解VS2017 Linux 上.NET Core調(diào)試
這篇文章主要介紹了詳解VS2017 Linux 上.NET Core調(diào)試,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04
.NET Core/Framework如何創(chuàng)建委托大幅度提高反射調(diào)用的性能詳解
反射是一種很重要的技術(shù),下面這篇文章主要給大家介紹了關(guān)于.NET Core/Framework如何創(chuàng)建委托大幅度提高反射調(diào)用性能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-09-09
ASP.NET Core Controller與IOC結(jié)合問題整理
在本篇文章里小編給大家整理了一篇關(guān)于ASP.NET Core Controller與IOC結(jié)合問題整理內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-01-01
gridview和checkboxlist的嵌套相關(guān)應(yīng)用
gridview和checkboxlist的嵌套使用,會(huì)有效的提高開發(fā)的效率,不過很多的童鞋們對(duì)此還是很陌生的,接下來將幫助童鞋們實(shí)現(xiàn)gridview和checkboxlist的嵌套使用,感興趣的朋友可以了解下,或許對(duì)你有所幫助2013-02-02

