先我們來看看jquery的ajax緩衝問題
jquery的ajax請求預設請求cache是true 也就是開啟的,dataType為script和jsonp時預設為false。現在我要在瀏覽器裡讀取緩衝,因為ajax請求的資料很大,請求一次就夠了。但是問題來了,在FF裡面,是沒有ajax緩衝的,也就是每次都會觸發ajax請求,這點和IE不一樣。所以在這裡就得注意,做個判斷,阻止觸發ajax事件。
function ajax_show(apartId,roomClass,sortTile){ HX_THIS_FANGXING_NUM=sortTile; huxing_pic_set_color(); var this_li=$('#title_'+sortTile); var cache=this_li.data("cache"); if(undefined!=cache){ var data_arr =cache.split('-'); xg_pic_links=data_arr[0];//緩衝記錄 layout_pic_links=data_arr[1]; layout_big_pic_links=data_arr[2]; product_links=data_arr[3]; xg_pic_deal_array(); xg_show_pic(xg_now_pic_id); }else{ $.ajax({//用JQ的緩衝cache在FF下還是會發起新請求 type: "POST", url: "index.php?m=content&c=index&a=ajax_all_pic", data: "apartId=123&roomClass=123", dataType:'text', success: function(backdata){ this_li.data('cache',backdata);//緩衝記錄 var data_arr =backdata.split('-'); xg_pic_links=data_arr[0]; layout_pic_links=data_arr[1]; layout_big_pic_links=data_arr[2]; product_links=data_arr[3]; xg_pic_deal_array(); xg_show_pic(xg_now_pic_id); } }); } }
通過 this_li.data('cache',backdata);//緩衝記錄 ,來做標記
緩衝解釋
jQuery全域對象裡的ajax方法提供了一些options來支援緩衝和Conditional GETs功能。
$.ajax({ ifModified: [true|false], cache: [true|false],});
ifModified選項定義的是在ajax調用的時候是否支援Conditional GETs功能。jQuery會自動幫我們處理伺服器端返回的名為Last-Modified的header值,然後在隨後的請求裡的header裡發送If-Modified-Since。這需要我們的MVC Controller要實現Conditional GETs功能才能用。Conditional GETs功能在http緩衝上下文中用於重新驗證緩衝中到期的條目。如果jQuery認為一個條目已經到期了,它首先會請求伺服器使用Conditional GETs功能重新驗證該條目,如果伺服器返回狀態代碼304(Not modified),jQuery會重新使用緩衝裡的該項目,這樣的話,我們可以節約很多流量去下載頁面內容。
cache選項基本上是覆蓋伺服器端返回的http header裡的所有關於緩衝的設定,如果設定cache選項為false的話,jQuery會在請求的URL後面附件一個時間戳記,以便區分之前的URL地址,這樣沒錯請求的內容都是最新的,也就是說瀏覽器每次接收的都是新地址,自然返回的都是最新資料。
讓我們來看幾個情境:
伺服器端響應裡設定No-Cache
伺服器端為王,如果伺服器端明確定義了response響應不能被緩衝的話,jQuery也無能為力。ajax裡的cache選項將被忽略。
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);}
伺服器端響應裡設定到期時間
伺服器端設定到期時間用於快取資料,該條目在用戶端將依據到期時間被緩衝。
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);}
用戶端從來不快取資料
用戶端決定每次都要最新的資料(不能使用緩衝),也就是說ajaxi裡的cache選項設定為false,不管伺服器端如何定義,jQuery每次請求的URL地址都是唯一不同的,目的是每次都擷取最新的內容。
JS代碼:
$(‘#expires_nocache‘).click(function () { $.ajax({ url: ‘/Home/Expires‘, ifModified: false, cache: false, // 這裡是關鍵 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);}
伺服器端和用戶端使用Conditional Gets功能驗證快取資料
用戶端將條目放在緩衝裡,在到期之後重新驗證。伺服器端必須實現Conditional GET功能(使用ETags或者last modified的header)。
JS代碼:
$(‘#expires_conditional‘).click(function () { $.ajax({ url: ‘/Home/ExpiresWithConditional‘, ifModified: true, // 這裡是關鍵 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中的代碼只是一個例子(非真實代碼),在真實的實現中,伺服器端應該能夠知道資料自從上次響應以後是否被修改過。