ASP.NET MVC中使用jQuery時(shí)的瀏覽器緩存問(wèn)題詳解
介紹
盡管jQuery在瀏覽器ajax調(diào)用的時(shí)候?qū)彺嫣峁┝撕芎玫闹С?,還是有必要了解一下如何高效地使用http協(xié)議。
首先要做的事情是在服務(wù)器端支持HTTP GET,定義不同的URL輸出不同的數(shù)據(jù)(MVC里對(duì)應(yīng)的就是action)。如果要使用同一個(gè)地址獲取不同的數(shù)據(jù),那就不對(duì)了,一個(gè)HTTP POST也不行因?yàn)镻OST不能被緩存。許多開(kāi)發(fā)人員使用POST主要有2個(gè)原因:明確了數(shù)據(jù)不能被緩存,或者是避免JSON攻擊(JSON返回?cái)?shù)組的時(shí)候可以被入侵)。
緩存解釋
jQuery全局對(duì)象里的ajax方法提供了一些options來(lái)支持緩存和Conditional GETs功能。
$.ajax({ ifModified: [true|false], cache: [true|false], });
ifModified選項(xiàng)定義的是在ajax調(diào)用的時(shí)候是否支持Conditional GETs功能。jQuery會(huì)自動(dòng)幫我們處理服務(wù)器端返回的名為L(zhǎng)ast-Modified的header值,然后在隨后的請(qǐng)求里的header里發(fā)送If-Modified-Since。這需要我們的MVC Controller要實(shí)現(xiàn)Conditional GETs功能才能用。Conditional GETs功能在http緩存上下文中用于重新驗(yàn)證緩存中過(guò)期的條目。如果jQuery認(rèn)為一個(gè)條目已經(jīng)過(guò)期了,它首先會(huì)請(qǐng)求服務(wù)器使用Conditional GETs功能重新驗(yàn)證該條目,如果服務(wù)器返回狀態(tài)碼304(Not modified),jQuery會(huì)重新使用緩存里的該項(xiàng)目,這樣的話,我們可以節(jié)約很多流量去下載頁(yè)面內(nèi)容。
cache選項(xiàng)基本上是覆蓋服務(wù)器端返回的http header里的所有關(guān)于緩存的設(shè)置,如果設(shè)置cache選項(xiàng)為false的話,jQuery會(huì)在請(qǐng)求的URL后面附件一個(gè)時(shí)間戳,以便區(qū)分之前的URL地址,這樣沒(méi)錯(cuò)請(qǐng)求的內(nèi)容都是最新的,也就是說(shuō)瀏覽器每次接收的都是新地址,自然返回的都是最新數(shù)據(jù)。
讓我們來(lái)看幾個(gè)場(chǎng)景:
服務(wù)器端響應(yīng)里設(shè)置No-Cache
服務(wù)器端為王,如果服務(wù)器端明確定義了response響應(yīng)不能被緩存的話,jQuery也無(wú)能為力。ajax里的cache選項(xiàng)將被忽略。
JS代碼:
$('#nocache').click(function () { $.ajax({ url: '/Home/NoCache', ifModified: false, cache: true, success: function (data, status, xhr) { $('#content').html(data.count); } }); });
C#代碼:
public ActionResult NoCache() { // 禁用緩存 Response.Cache.SetCacheability(HttpCacheability.NoCache); return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }
服務(wù)器端響應(yīng)里設(shè)置過(guò)期時(shí)間
服務(wù)器端設(shè)置過(guò)期時(shí)間用于緩存數(shù)據(jù),該條目在客戶端將依據(jù)過(guò)期時(shí)間被緩存。
JS代碼:
$('#expires').click(function () { $.ajax({ url: '/Home/Expires', ifModified: false, cache: true, success: function (data, status, xhr) { $('#content').html(data.count); } }); });
C#代碼:
public ActionResult Expires() { Response.Cache.SetExpires(DateTime.Now.AddSeconds(5)); return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }
客戶端從來(lái)不緩存數(shù)據(jù)
客戶端決定每次都要最新的數(shù)據(jù)(不能使用緩存),也就是說(shuō)ajaxi里的cache選項(xiàng)設(shè)置為false,不管服務(wù)器端如何定義,jQuery每次請(qǐng)求的URL地址都是唯一不同的,目的是每次都獲取最新的內(nèi)容。
JS代碼:
$('#expires_nocache').click(function () { $.ajax({ url: '/Home/Expires', ifModified: false, cache: false, // 這里是關(guān)鍵 success: function (data, status, xhr) { $('#content').html(data.count); } }); });
C#代碼:
public ActionResult Expires() { // 不管服務(wù)器端怎么設(shè)置都沒(méi)用 Response.Cache.SetExpires(DateTime.Now.AddSeconds(5)); return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }
服務(wù)器端和客戶端使用Conditional Gets功能驗(yàn)證緩存數(shù)據(jù)
客戶端將條目放在緩存里,在過(guò)期之后重新驗(yàn)證。服務(wù)器端必須實(shí)現(xiàn)Conditional GET功能(使用ETags或者last modified的header)。
JS代碼:
$('#expires_conditional').click(function () { $.ajax({ url: '/Home/ExpiresWithConditional', ifModified: true, // 這里是關(guān)鍵 cache: true, success: function (data, status, xhr) { $('#content').html(data.count); } }); });
C#代碼:
public ActionResult ExpiresWithConditional() { if (Request.Headers["If-Modified-Since"] != null && Count % 2 == 0) { return new HttpStatusCodeResult((int)HttpStatusCode.NotModified); } Response.Cache.SetExpires(DateTime.Now.AddSeconds(5)); Response.Cache.SetLastModified(DateTime.Now); return Json(new { count = Count++ }, JsonRequestBehavior.AllowGet); }
上述MVC action中的代碼只是一個(gè)例子(非真實(shí)代碼),在真實(shí)的實(shí)現(xiàn)中,服務(wù)器端應(yīng)該能夠知道數(shù)據(jù)自從上次響應(yīng)以后是否被修改過(guò)。
總結(jié)
詳細(xì)通過(guò)這4個(gè)場(chǎng)景,大家應(yīng)該了解了ajax請(qǐng)求的緩存技術(shù)了吧,我就不做總結(jié)了。
英文原文來(lái)自:http://weblogs.asp.net/cibrax/archive/2012/02/10/hacking-the-browser-cache-with-jquery-and-asp-net-mvc.aspx
以上這篇ASP.NET MVC中使用jQuery時(shí)的瀏覽器緩存問(wèn)題詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
asp.net?core實(shí)體類生產(chǎn)CRUD后臺(tái)管理界面
這篇文章主要為大家介紹了asp.net?core實(shí)體類生產(chǎn)CRUD后臺(tái)管理界面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05ASP.NET Core中的Razor頁(yè)面實(shí)現(xiàn)路由功能
本文詳細(xì)講解了ASP.NET Core中的Razor頁(yè)面實(shí)現(xiàn)路由功能的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02ASP.NET 水晶報(bào)表打印功能實(shí)現(xiàn)代碼
ASP.NET下的水晶報(bào)表打印,據(jù)我所知有以下幾種辦法可以打印2008-11-11ASP.NET實(shí)現(xiàn)偽靜態(tài)網(wǎng)頁(yè)方法小結(jié)
這篇文章主要介紹了ASP.NET實(shí)現(xiàn)偽靜態(tài)網(wǎng)頁(yè)方法小結(jié),主要包括了利用Httphandler實(shí)現(xiàn)URL重寫(xiě)、地址重寫(xiě)、利用Mircosoft URLRewriter.dll實(shí)現(xiàn)頁(yè)面?zhèn)戊o態(tài)等,需要的朋友可以參考下2014-09-09ASP.NET也像WinForm程序一樣運(yùn)行的實(shí)現(xiàn)方法
我們今天要談到的是讓ASP.NET的程序也像WinForm一樣的運(yùn)行,這樣就不需要安裝IIS或者Visual Studio這樣的特定環(huán)境了2012-01-01ASP.NET批量操作基于原生html標(biāo)簽的無(wú)序列表的三種方法
無(wú)序列表被大量使用,ASP.NET雖然內(nèi)置了BulletedList控件,用于創(chuàng)建和操作無(wú)序列表,但感覺(jué)不太好用2014-09-09ASP.NET?Core?MVC中使用Tag?Helper組件
這篇文章介紹了ASP.NET?Core?MVC中使用Tag?Helper組件的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02