ASP.NET Core中的Http緩存使用
Http
響應(yīng)緩存可減少客戶端或代理對web
服務(wù)器發(fā)出的請求數(shù)。響應(yīng)緩存還減少了web
服務(wù)器生成響應(yīng)所需的工作量。響應(yīng)緩存由Http
請求中的header
控制。
而ASP.NET Core
對其都有相應(yīng)的實現(xiàn),并不需要了解里面的工作細(xì)節(jié),即可對其進(jìn)行良好的控制。
了解Http緩存
Http
協(xié)議中定義了許多緩存,但總體可以分為強緩存和協(xié)商緩存兩類。
強緩存
強緩存是指緩存命中時,客戶端不會向服務(wù)器發(fā)請求,瀏覽器F12
能看到響應(yīng)狀態(tài)碼為200
,size
為from cache
,它的實現(xiàn)有以下幾種方式:
Expires - 絕對時間
示例:Expires:Thu,31 Dec 2037 23:59:59 GMT
,就表示緩存有效期至2037年12月31日,在這之前瀏覽器都不會向服務(wù)器發(fā)請求了(除非按F5
/Ctrl+F5
刷新)。
Cache-Control - 相對時間/更多控制
絕對時間是一個絕對時間,因為計算時不方便;而且服務(wù)端是依據(jù)服務(wù)器的時間來返回,但客戶端卻需要依據(jù)客戶的時間來判斷,因此也容易失去控制。
Cache-Control
有以下選項(可以多選):
- max-age: 指定一個時間長度,在這個時間段內(nèi)緩存是有效的,單位是秒(s)。例如設(shè)置Cache-Control:max-age=31536000,也就是說緩存有效期為31536000/24/60/60=365天。
- s-maxage: 同max-age,覆蓋max-age、Expires,但僅適用于共享緩存,在私有緩存中被忽略。
- public: 表明響應(yīng)可以被任何對象(發(fā)送請求的客戶端、代理服務(wù)器等等)緩存。
- private: 表明響應(yīng)只能被單個用戶(可能是操作系統(tǒng)用戶、瀏覽器用戶)緩存,是非共享的,不能被代理服務(wù)器緩存。
- no-cache: 強制所有緩存了該響應(yīng)的用戶,在使用已緩存的數(shù)據(jù)前,發(fā)送帶驗證器的請求到服務(wù)器。(不是字面意思上的不緩存)
- no-store: 禁止緩存,每次請求都要向服務(wù)器重新獲取數(shù)據(jù)。
- must-revalidate: 指定如果頁面是過期的,則去服務(wù)器進(jìn)行獲取。(意思是瀏覽器在某些情況下,緩存失效后仍可使用老緩存,加了這個頭,失效后就必須驗證,并不是字面上有沒有過期都驗證)
其中最有意思的要數(shù)no-cache
和must-revalidate
了,因為它們的表現(xiàn)都不是字面意義。
no-cache
并不是字面上的不緩存,而是會一直服務(wù)端驗證(真實意義很像字面上的must-revalidate
)。
而must-revalidate
是只是為了給瀏覽器強調(diào),緩存過期后,千萬要遵守約定重新驗證。
協(xié)商緩存
協(xié)商緩存是指緩存命中時,服務(wù)器返回Http
狀態(tài)碼為304
但無內(nèi)容(Body
),沒命中時返回200
有內(nèi)容。
在要精細(xì)控制時,協(xié)商緩存比強緩存更有用,它有Last-Modified
和ETag
兩種。
Last-Modified/If-Modify-Since(對比修改時間)
示例:
服務(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(對比校驗碼)
服務(wù)器:ETag: W/"0a0b8e05663d11:0"
客戶端:If-None-Match: W/"0a0b8e05663d11:0"
清緩存要點
- 按
F5
刷新時,強緩存失效 - 按
Ctrl+F5
刷新時 強緩存和協(xié)商緩存都失效
ASP.NET Core的Http緩存
ASP.NET Core
中提供了ResponseCacheAttribute
來實現(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
定義了緩存的位置,是重點:
// 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ù)器的選項。
其中Duration
表示緩存時間,單位為秒,它將翻譯為max-age
。
另外可以通過VaryByHeader
和VaryByQueryKeys
來配置緩存要不要通過header
和query string
來變化,其中VaryByHeader
是通過Http
協(xié)議中的Vary
頭來實現(xiàn)的,VaryByQueryKeys
必須通過Middleware
來實現(xiàn)。
不要誤會,所有ResponseCacheAttribute
的屬性配置都不會在服務(wù)端緩存你的響應(yīng)數(shù)據(jù)(雖然你可能有這種錯覺),它和輸出緩存不同,它沒有狀態(tài),只用來做客戶端強緩存。
如果不想緩存,則設(shè)置NoStore = true
,它會設(shè)置cache-control: no-store
,我們知道no-store
的真實意思是不緩存。一般還會同時設(shè)置Location = ResponseCacheLocation.None
,它會設(shè)置cache-control: no-cache
(真實意思是表示一定會驗證)。
注意單獨設(shè)置Location = ResponseCacheLocation.None
而不設(shè)置NoStore
并不會有任何效果。
示例1
這是一個很典型的使用示例:
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#
代碼來驗證:
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
級別上,表示整個Controller
都受到緩存的影響。
CacheProfileName示例
另外,如果需要共用緩存配置,可以使用CacheProfileName
,將緩存提前定義好,之后直接傳入這個定義名即可使用:
.ConfigureServices(s => { s.AddControllers(o => { o.CacheProfiles.Add("3500", new CacheProfile { Duration = 3500, Location = ResponseCacheLocation.Client, }); }); });
這樣我就定義了一個名為3500
的緩存,稍后在Controller
中我只需傳入CacheProfileName = 3500
即可:
public class HomeController : Controller { [ResponseCache(CacheProfileName = "3500")] public IActionResult Data() { return Json(DateTime.Now); } }
總結(jié)
Http
緩存分為強緩存和協(xié)商緩存,ASP.NET Core
提供了便利的ResponseCacheAttribute
實現(xiàn)了強緩存,還能通過Profile
來批量配置多個緩存點。
但ASP.NET MVC
并沒有提供協(xié)商緩存實現(xiàn),因為這些多半和業(yè)務(wù)邏輯相關(guān),需要自己寫代碼。靜態(tài)文件是特例,Microsoft.AspNetCore.StaticFiles
中提供有,因為靜態(tài)文件的邏輯很清晰。
ASP.NET
中的OutputCacheAttribute
在ASP.NET Core
中不復(fù)存在,取而代之的是app/services.AddResponseCaching()
,這些和Http
協(xié)議不相關(guān)。
有機會我會具體聊聊這些緩存。
到此這篇關(guān)于ASP.NET Core中的Http緩存使用的文章就介紹到這了,更多相關(guān)ASP.NET Core Http緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET設(shè)計網(wǎng)絡(luò)硬盤之上傳文件實現(xiàn)代碼
用戶最終是要和文件打交道的,文件夾僅僅是用來方便管理的。文件的上傳和下載也就成為“網(wǎng)絡(luò)硬盤”功能設(shè)計中的重要一環(huán)2012-10-10Excel、記事本數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫的實現(xiàn)方法
將手機號批量導(dǎo)入數(shù)據(jù)庫。思路:先將要導(dǎo)入的文件傳上項目里,然后讀取文件的每行數(shù)據(jù)并插入數(shù)據(jù)庫,操作完后再將上傳的文件刪除2013-10-10C#,winform,ShowDialog,子窗體向父窗體傳值
窗體的show方法,沒有給調(diào)用代碼任何通知,如果需要通知,使用showdialog是一種好的選擇。 在調(diào)用show方法后,show方法后面的代碼會立即執(zhí)行,2008-08-08服務(wù)器讀取EXCEL不安裝OFFICE如何實現(xiàn)
用asp.net做了一簡單的游戲管理后臺,涉及到了上傳Excel導(dǎo)入數(shù)據(jù)的功能,在本地開發(fā)實現(xiàn)都好好的,可已上傳的服務(wù)器上就悲劇了,下面有個不錯的解決方法,大家可以參考下2014-03-03ASP.NET oledb連接Access數(shù)據(jù)庫的方法
這篇文章主要介紹了ASP.NET oledb連接Access數(shù)據(jù)庫的方法,需要的朋友可以參考下2015-01-01ASP.NET Core MVC/WebApi基礎(chǔ)系列2
這篇文章主要介紹了.NET Core當(dāng)中的模型綁定系統(tǒng)、模型綁定原理、自定義模型綁定、混合綁定、ApiController特性本質(zhì)。2019-04-04ASP.NET Global.asax應(yīng)用程序文件簡介
Global.asax 文件,有時候叫做 ASP.NET 應(yīng)用程序文件,提供了一種在一個中心位置響應(yīng)應(yīng)用程序級或模塊級事件的方法。2009-03-03ASP.NET?Core?WebApi返回結(jié)果統(tǒng)一包裝實踐記錄
本文主要是展示了針對ASP.NET Core WeApi結(jié)果統(tǒng)一返回格式的相關(guān)操作,通過示例我們一步一步的展示了完成這一目標(biāo)的不斷升級的實現(xiàn),雖然整體看起來比較簡單,但是卻承載著筆者一次又一次的思考升級2022-04-04