一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

用ASP.NET控制HTTP請求過程中瀏覽器緩存問題解析

西西 ? 來源:博客園 ? 作者: Fish Li ? 2020-09-22 15:11 ? 次閱讀

在我們開發(fā)一個ASP.NET網(wǎng)站的過程中,其實(shí)有很多地方都是可以使用緩存的, 只是由于ASP.NET是一種基于服務(wù)端的開發(fā)平臺,自然我們也經(jīng)常在服務(wù)端的代碼中使用各類緩存技術(shù), 然而,由于WEB應(yīng)用程序的服務(wù)對象是客戶端的瀏覽器,通常來說,我們并不能直接控制瀏覽器的行為,但是, 瀏覽器卻可以根據(jù)后臺網(wǎng)站的指示,采取一些優(yōu)化的方式來更快地呈現(xiàn)頁面。 客戶端瀏覽器也有自己的緩存機(jī)制,通常瀏覽器也使用緩存來優(yōu)化一些頁面的顯示過程, 不過,我們并不能直接使用C#代碼控制瀏覽器的緩存操作,但我們可以告訴瀏覽器如何使用緩存,從而達(dá)到優(yōu)化網(wǎng)站性能的目的。

這次博客的主題是:用ASP.NET控制HTTP請求過程中瀏覽器緩存的一些方法。

正常的HTTP請求過程

在開始介紹瀏覽器在HTTP請求過程前,我想有必要先來看一下瀏覽器請求一個普通ASPX頁面的過程。

說明:本文在介紹HTTP請求過程時,會大量使用Fiddler來分析具體的請求過程。

上圖是一個普通的ASPX頁面的請求過程,說它普通是因?yàn)椋何以趧?chuàng)建這個頁面后,沒對它做任何緩存方面的處理。

圖片中我們可以可以看到服務(wù)器的響應(yīng)狀態(tài)為:HTTP/1.1 200 OK,這是一個服務(wù)器成功響應(yīng)的標(biāo)志。

另外,要注意圖片中的Cache響應(yīng)頭部分,我之所以就紅線框出來,是想提醒您注意這塊的內(nèi)容將在后面的小節(jié)中發(fā)生改變, 到時候請注意對比它們。而這里所反映的情況其實(shí)也只是默認(rèn)值而已,它并不表示此頁面需要緩存。

緩存頁的請求過程

下面再來看一個緩存頁面的請求過程:

對比上一張圖片中可以看出,現(xiàn)在多了【max-age】,【Expires】以及【Last-Modified】這三個響應(yīng)頭。

這三個頭的含義如下:

1. max-age,Expires:要表達(dá)的意思基本差不多。max-age表示某次HTTP的響應(yīng)結(jié)果應(yīng)該緩存多少秒。

而Expires是說某次HTTP的響應(yīng)結(jié)果應(yīng)緩存到什么時候過期,此時間是一個UTC時間。

另一個Date頭表示HTPP響應(yīng)的發(fā)出時間,我們可以發(fā)現(xiàn) Date + max-age = Expires

2. Last-Modified:服務(wù)端告訴客戶端本次響應(yīng)返回的HTTP文檔的最后修改時間。這個頭與304的實(shí)現(xiàn)有關(guān),后面再來解釋。

分析了HTTP請求過程后,我們再來看一下服務(wù)端的頁面是什么樣子的:

注意:上面代碼中最關(guān)鍵的一行代碼為:

《%@ OutputCache Duration=“10” VaryByParam=“None” %》

正是由于使用了這個OutputCache指令,最后才會輸出上面那幾個響應(yīng)頭,用來告訴瀏覽器此頁面需要緩存10秒鐘。

說到這里,可能有些人想有疑惑了:緩存頁在什么時候會起到什么作用呢?

為了演示緩存頁所帶來的現(xiàn)實(shí)意義,我將點(diǎn)擊頁面的這些鏈接并以截圖的形式來說明:在一系列請求過程中頁面的顯示情況, 并以頁面的顯示結(jié)果來分析緩存所起的作用。

先來看看這個頁面的顯示截圖:

頁面很簡單,主要是顯示了頁面的生成時間與一個刷新鏈接。 從上面提供的頁面代碼,我們應(yīng)該能知道這個頁面如果是由服務(wù)端生成的,則會顯示當(dāng)前的時間。

不過呢,當(dāng)我一直(頻繁)點(diǎn)擊【刷新本頁】那個鏈接時,頁面的時間并沒有發(fā)生改變,當(dāng)我發(fā)現(xiàn)時間改變時,頁面已顯示成這個樣子了:

由于測試過程中,我一直打開了Fiddler,正好我也把Fiddler監(jiān)視到的請求結(jié)果截圖下來了:

從Fiddler中,我看到FireFox其實(shí)只發(fā)生了二次請求,但我點(diǎn)擊那個【刷新本頁】起碼超過10次。

以上的這一切,只說明一個事實(shí):如果頁面需要跳轉(zhuǎn)到某個緩存頁時,且那個緩存頁還沒過期,那么瀏覽器并不會發(fā)起到服務(wù)器的請求,而是使用緩存頁。

小結(jié):頁面緩存所帶來的好處是:緩存頁面在過期前,用戶通過點(diǎn)擊跳轉(zhuǎn)鏈接所引發(fā)的后續(xù)訪問,并不會再次請求服務(wù)器。 這對服務(wù)器來說可以減少許多訪問次數(shù),因此使用這個特性可以很好地改善程序性能。

緩存頁的服務(wù)端編程

前面演示了使用OutputCache指令所產(chǎn)生的緩存頁的效果,由于那些指令需要在頁面的設(shè)計階段就寫到頁面上,因此顯得不夠靈活, 不能在運(yùn)行時調(diào)整,雖然ASP.NET也允許我們使用CacheProfile來引入定義在Web.config中的配置,但配置還是沒有運(yùn)行時的代碼靈活。 我們再來看看如何用代碼來實(shí)現(xiàn)上面的效果。

其實(shí)用代碼實(shí)現(xiàn)緩存頁也很簡單,只需要這樣就可以了:

protected void Page_Load(object sender, EventArgs e)

{

Response.Cache.SetCacheability(HttpCacheability.Public);

Response.Cache.SetExpires(DateTime.Now.AddSeconds(10.0));

}

其實(shí)關(guān)鍵也就是對Response.Cache的調(diào)用。

注意:Response.Cache與我上篇 【細(xì)說 ASP.NET Cache 及其高級用法】博客所講的Cache不是一回事,二者完全不相干。

Response.Cache提供:用于設(shè)置緩存特定的 HTTP 標(biāo)頭的方法和用于控制 ASP.NET 頁輸出緩存的方法。

我們還是來說前面的二段示例代碼??赡苡行┤藭耄鼈冏罱K的結(jié)果真的會是一致的嗎?

要想回答這個問題,我想有必要看一下前面用OutputCache指令的那個頁面最終運(yùn)行的代碼是個什么樣子的。

在ASP.NET的臨時編譯目錄中,我找到了前面那個文件的一個由ASP.NET處理后的版本:

我們可以看到頁面針對OutputCache指令的設(shè)置,最終會調(diào)用Page類定義一個方法中:

protected internal virtual void InitOutputCache(OutputCacheParameters cacheSettings)

那個方法實(shí)在太長,最終的處理方式也還是在調(diào)用this.Response.Cache,有興趣的可以自己去看看那個方法。 至于這個方法的參數(shù)為什么是OutputCacheParameters,我想這個容易理解:方便將OutputCache指令的參數(shù)全部一起傳入嘛。

所以,也正因?yàn)檫@個緣故,我們也可以直接在代碼中調(diào)用Response.Cache的一些方法來實(shí)現(xiàn)相同的效果, 由于代碼可以在運(yùn)行時根據(jù)各種參數(shù)調(diào)整緩存策略,因此會更加靈活,而且可以采用基類的繼承方式來簡化實(shí)現(xiàn)。

注意:如果使用OutputCache指令再配合OutputCache Module的使用,可以實(shí)現(xiàn)304的效果。

什么是304應(yīng)答?

通過前面的示例,我們已經(jīng)看到緩存帶來的好處:那就是可以減少到服務(wù)器的訪問,由于不訪問服務(wù)器就能顯示頁面,這對于服務(wù)器來說, 能減輕一定的訪問壓力。但是,如果用戶強(qiáng)制刷新瀏覽器,那么瀏覽器將會忽略緩存頁,直接向服務(wù)器重新發(fā)起請求。

也就是說:緩存頁在用戶強(qiáng)制刷新瀏覽器時會無效。

但是,我們之所以使用緩存頁,是因?yàn)槲覀兿M嬖V瀏覽器:這些數(shù)據(jù)在一定時間內(nèi),并不會發(fā)生變化,因此根本不需要再次請求服務(wù)器了。 然而,我們不能阻止用戶的行為。由于瀏覽器的重新訪問,我們原來設(shè)想的緩存想法將會落空,最后的結(jié)果是: 頁面在服務(wù)器中重新執(zhí)行,產(chǎn)生的HTML代碼將重新發(fā)送到客戶端。而這一重新刷新的結(jié)果可能也是無意義的,因?yàn)閿?shù)據(jù)可能根本沒有發(fā)生變化, 因此得到的頁面也是不可能有變化的。

再來舉個簡單的例子來說吧:客戶端要瀏覽一張圖片。 當(dāng)瀏覽器第一次要訪問圖片時,瀏覽器肯定是沒有它的任何緩存記錄的,此時它去訪問服務(wù)器,服務(wù)器也返回圖片的內(nèi)容了。 但由于圖片可能會被多個頁面所引用,而它被修改的可能性是很小的。 因此沒有必要為同一瀏覽器的多次請求都去讀取圖片并返回圖片的內(nèi)容,這樣做既影響性能也學(xué)浪費(fèi)帶寬。 于是,像IIS這樣服務(wù)器軟件針對這類靜態(tài)文件的訪問時,都會在響應(yīng)頭上輸出一些標(biāo)記,用來告之瀏覽器這個文件你可以緩存起來了。

還是回到前面所說的【用戶強(qiáng)制刷新】問題,此時的IIS又會如何處理呢?請看下圖:

注意哦,此時除了HTTP狀態(tài)碼變成304之外,沒有任何數(shù)據(jù)返回哦。

為了讓您對304應(yīng)答有個深刻的印象,我截了一張狀態(tài)碼為200的圖片響應(yīng)結(jié)果:

通過這二張圖片的對比,現(xiàn)在看清楚了吧:304和200并不只是數(shù)字上的差別,最重要的差別在于有沒有返回結(jié)果。

沒有返回結(jié)果,瀏覽器該如何顯示?

您會有這樣的疑慮嗎?

其實(shí)不用擔(dān)心,此時瀏覽器會使用它緩存版本來顯示。也就是說:不管用戶如何強(qiáng)制刷,服務(wù)器就是不返回結(jié)果,但仍然可以正常顯示。

顯然,這個效果就是我們想要的。

前面所說的緩存頁遭用戶強(qiáng)刷的問題,如果采用這種方法,就比較完美了。

不過,有一點(diǎn)我要提醒您:Visual Studio自帶的那個WebDev.WebServer.exe不支持304應(yīng)答,所以您就不要拿它試驗(yàn)了,不會有結(jié)果的。

如何編程實(shí)現(xiàn)304應(yīng)答

前面我們看到了304應(yīng)答的效果。不過,在ASP.NET中,我們開發(fā)的程序,是動態(tài)頁面,而不是圖片, 我們更希望某個頁面能以這種方式緩存一段時間,我想這個需求或許會更有意義。

下面,我就來演示如何通過編程的方式實(shí)現(xiàn)它。

接下來的示例中,頁面的顯示還是那個樣,顯示頁面在服務(wù)器上產(chǎn)生的時間,時間變化了,說明頁面被重新執(zhí)行了。

重新截一系列的圖片,我認(rèn)為意義也不大,我就截一張圖片展現(xiàn)多次強(qiáng)刷而產(chǎn)生的過程

上圖反映了我多次請求某個ASPX頁面的過程,從圖片中可以看出,只有第一次是200的響應(yīng),后面全是304,是您所期待的結(jié)果吧。

再來看看它的實(shí)現(xiàn)代碼吧:

雖然代碼并不復(fù)雜,但我還是打算來解釋一下:

在瀏覽器第一次請求頁面時,會執(zhí)行SetLastModified的調(diào)用,它會在響應(yīng)時輸出一個“Last-Modified”這個響應(yīng)頭, 然后,當(dāng)瀏覽器再次訪問這個頁面時,會將上次請求所獲取的“Last-Modified”頭的內(nèi)容 , 以“If-Modified-Since”這個請求頭的形式發(fā)給服務(wù)端,此時服務(wù)器就可以根據(jù)具體邏輯來判斷要不要使用304應(yīng)答了。

在前面的請求圖片的示例中,服務(wù)器以圖片文件的最后修改時間做為“Last-Modified”發(fā)給瀏覽器, 瀏覽器在后續(xù)請求那張圖片時,又以“If-Modified-Since”的形式告之服務(wù)端,此時服務(wù)端只要再次檢查一下這張圖片就知道圖片在上次訪問后有沒有發(fā)生修改, 如果沒有修改,當(dāng)然就以304的形式告之瀏覽器:繼續(xù)使用緩存版本。

還是前面的請求圖片的示例,其實(shí)服務(wù)端還使用了另一對【請求/響應(yīng)】頭:

這二個頭的使用方式是:服務(wù)端輸出一個ETag頭,瀏覽器在接收后,以If-None-Match的形式在后續(xù)請求中發(fā)送到服務(wù)端, 供服務(wù)端判斷是否使用304應(yīng)答。

“Last-Modified”與“ETag”這二者,事實(shí)上只需要使用一個就夠了,關(guān)鍵還是看服務(wù)端如何處理它們,瀏覽器只是在接收后,下次再發(fā)出去而已。

不過,前面的示例代碼并沒有使用緩存頭,事實(shí)上,也可以帶上它,這樣可以盡量減少對服務(wù)器的訪問,畢竟用戶不會一直強(qiáng)刷瀏覽器。 這二種方式雖然有較大差別,但它們絕對是可以互補(bǔ)的。

為了能形象的描繪緩存頁(或者其它文檔)的請求過程,我畫了張示意圖供大家參考:

如何避開HTTP緩存

前面小節(jié)中,介紹了二種方法使用瀏覽器的緩存。但有些時候可能反而希望瀏覽器能放棄它緩存的結(jié)果。 現(xiàn)在的瀏覽器都有緩存功能,尤其是對一些靜態(tài)文件,比如:圖片,JS,CSS, HTML文件,都能緩存。 但有時候我們需要更新CSS, JS文件呢,瀏覽器如果還使用它的緩存版本,顯然就有問題了。 而且有些網(wǎng)站使用了URL重寫,使原來的動態(tài)頁面擴(kuò)展名也變成靜態(tài)的HTML文件了, 因此,仍然希望瀏覽器在某些時候能夠不要緩存這些偽靜態(tài)頁面。

此時,我們就希望瀏覽器放棄從HTTP請求所獲得的結(jié)果了。 一般說來,瀏覽器在處理(它認(rèn)為的)靜態(tài)文件時,會按照URL為kEY來保存那些緩存結(jié)果, 因此,通常的解決辦法也就是修改URL,比如:原來是請求abc.js的,要改成abc.js?t=23434,后面要跟上一個參數(shù), 讓以前的緩存不起作用。至于參數(shù)t的取值可以根據(jù)文件的最后修改時間,也可以手工指定,總之只要改變它就可以了。

但是,對于偽靜態(tài)的頁面,我們不能再使用這種方法了,原因就不用解釋了吧。

那么,可以采用在服務(wù)端輸出一個響應(yīng)頭,通過響應(yīng)頭的方式告之瀏覽器,不要緩存此文件。 比如,可以調(diào)用這個方法:

Response.Cache.SetNoStore();

它會生成這樣的響應(yīng)頭內(nèi)容:

Cache-Control: private, no-store

許多瀏覽器都能識別它。還有另一種方法是設(shè)置一個已過期的過期時間。

前面所說的在URL中加額外參數(shù)的做法,在JS中也比較常用,比如 JQuery就支持讓某個Ajax請求不緩存, 它的方式就是設(shè)置{cache: false},最終它便會在生成的URL中加上一個臨時參數(shù),以保證后面的請求的地址是不重復(fù)的, 最終達(dá)到避開緩存的目的。JQuery的使用太簡單,我就不再給出示例代碼了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • HTTP
    +關(guān)注

    關(guān)注

    0

    文章

    516

    瀏覽量

    32290
  • ASP
    ASP
    +關(guān)注

    關(guān)注

    0

    文章

    98

    瀏覽量

    34327
  • 瀏覽器
    +關(guān)注

    關(guān)注

    1

    文章

    1040

    瀏覽量

    35975
收藏 人收藏

    評論

    相關(guān)推薦

    nginx強(qiáng)緩存和協(xié)商緩存介紹

    強(qiáng)緩存直接告訴瀏覽器:在緩存過期前,無需與服務(wù)通信,直接使用本地緩存。
    的頭像 發(fā)表于 04-01 16:01 ?205次閱讀

    HTTP和HTTPS的關(guān)鍵區(qū)別

    ,數(shù)據(jù)傳輸過程中并未加密,所以它比較容易被中間人攻擊。無狀態(tài),即不能保存每次提交的信息,如果用戶發(fā)來一個新的請求,服務(wù)無法知道它是否與上次請求有關(guān)聯(lián)。
    的頭像 發(fā)表于 03-25 15:34 ?320次閱讀
    <b class='flag-5'>HTTP</b>和HTTPS的關(guān)鍵區(qū)別

    Spire.PDFViewer for ASP.NET強(qiáng)大的PDF查看組件

    Spire.PDFViewer for ASP.NET 是一款強(qiáng)大的 PDF 查看組件,它允許開發(fā)人員從文件中加載各種 PDF 文檔并且可以在網(wǎng)頁上瀏覽 PDF 文檔。該組件還支持瀏覽 PDF
    的頭像 發(fā)表于 02-13 09:17 ?291次閱讀
    Spire.PDFViewer for <b class='flag-5'>ASP.NET</b>強(qiáng)大的PDF查看組件

    HTTP網(wǎng)絡(luò)通訊過程

    過程 客戶端(發(fā)送方組包) 1)HTTP 瀏覽器 解析 URL (協(xié)議、域名、資源路徑) 生成? HTTP
    的頭像 發(fā)表于 01-20 09:07 ?354次閱讀
    <b class='flag-5'>HTTP</b>網(wǎng)絡(luò)通訊<b class='flag-5'>過程</b>

    E2000 Speedometer測試瀏覽器性能

    。 Speedometer具有以下顯著特點(diǎn),使其在眾多基準(zhǔn)測試工具脫穎而出: 真實(shí)性:通過模擬真實(shí)用戶交互,Speedometer的測試結(jié)果能夠真實(shí)反映瀏覽器在實(shí)際使用的性能表現(xiàn)。 靈活性:支持多任務(wù)
    發(fā)表于 01-10 21:33

    服務(wù)如何處理 HTTP 請求

    請求。這是服務(wù)等待接收HTTP請求的第一步。 接受連接 :當(dāng)客戶端(如Web瀏覽器)發(fā)起連接請求
    的頭像 發(fā)表于 12-30 09:37 ?484次閱讀

    如何調(diào)試 HTTP 請求和響應(yīng)

    調(diào)試HTTP請求和響應(yīng)是Web開發(fā)和網(wǎng)絡(luò)編程的一個重要技能。以下是一些步驟和工具,可以幫助你調(diào)試HTTP請求和響應(yīng): 1. 使用
    的頭像 發(fā)表于 12-30 09:28 ?946次閱讀

    HTTP 協(xié)議的工作原理

    的主要功能是使瀏覽器能夠訪問服務(wù)上的資源,如網(wǎng)頁、圖片、視頻等。 2. HTTP請求 HTTP請求
    的頭像 發(fā)表于 12-30 09:21 ?697次閱讀

    HTTP緩存頭的使用 本地緩存與遠(yuǎn)程緩存的區(qū)別

    HTTP緩存頭是一組HTTP響應(yīng)頭,它們控制瀏覽器和中間代理服務(wù)如何
    的頭像 發(fā)表于 12-18 09:41 ?343次閱讀

    Web緩存的類型及功能分析

    速度,降低了延遲,并提高了網(wǎng)站的可用性。 Web緩存的類型 Web緩存主要分為以下幾種類型: 瀏覽器緩存(Browser Cache) 功能 :瀏覽
    的頭像 發(fā)表于 12-18 09:35 ?600次閱讀

    AWTK 最新動態(tài):支持瀏覽器控件

    導(dǎo)讀AWTK瀏覽器控件,基于webview項(xiàng)目實(shí)現(xiàn),將瀏覽器嵌入到AWTK應(yīng)用程序,讓開發(fā)者可以方便的集成在線幫助和調(diào)用地圖等功能。awtk-widget-web-view是基于webview實(shí)現(xiàn)的AWTK
    的頭像 發(fā)表于 11-20 01:05 ?497次閱讀
    AWTK 最新動態(tài):支持<b class='flag-5'>瀏覽器</b>控件

    寫一個Chrome瀏覽器插件

    一、什么是瀏覽器插件 瀏覽器插件是依附于瀏覽器,用來拓展網(wǎng)頁能力的程序。插件具有監(jiān)聽瀏覽器事件、獲取和修改網(wǎng)頁元素、攔截網(wǎng)絡(luò)請求、添加快捷菜
    的頭像 發(fā)表于 11-18 17:12 ?859次閱讀
    寫一個Chrome<b class='flag-5'>瀏覽器</b>插件

    HTTP相關(guān)返回值異常如何解決(上篇)

    協(xié)議。它是萬維網(wǎng)(WWW)的基礎(chǔ),允許客戶端(通常是網(wǎng)頁瀏覽器)與服務(wù)之間進(jìn)行通信。以下是對 HTTP 的一些基本介紹: 基本概念 請求-響應(yīng)模型:
    的頭像 發(fā)表于 10-20 16:40 ?693次閱讀
    <b class='flag-5'>HTTP</b>相關(guān)返回值異常如何解決(上篇)

    跨域問題是由瀏覽器的同源策略造成的

    瀏覽器
    jf_62215197
    發(fā)布于 :2024年08月27日 07:51:42

    不只是前端,后端、產(chǎn)品和測試也需要了解的瀏覽器知識(二)

    繼上篇《 不只是前端,后端、產(chǎn)品和測試也需要了解的瀏覽器知識(一)》介紹了瀏覽器的基本情況、發(fā)展歷史以及市場占有率。 本篇文章將介紹瀏覽器基本原理。 在掌握基本原理后,通過技術(shù)深入,在研發(fā)過程
    的頭像 發(fā)表于 08-12 14:32 ?544次閱讀
    不只是前端,后端、產(chǎn)品和測試也需要了解的<b class='flag-5'>瀏覽器</b>知識(二)