緩存無處不在,有客戶端緩存,服務端緩存,代理服務器緩存等等。和前端相關的緩存通常都是指http緩存,也就是瀏覽器緩存。javascript
就是說ajax請求以後,會把請求的url和返回的響應結果保存在緩存中,當下一次調用ajax發送相同的請求時,瀏覽器會從緩存中把數據取出來,這是爲了提升頁面的響應速度和用戶體驗,何時會出現這個現象呢,就是要這兩次的請求url和請求參數徹底同樣的時候,瀏覽器就不會與服務器交互。css
如今說一下緩存的好處,好處顯而易見嘛,就是說請求一些靜態資源,js,css,圖片這些,不會變化的資源,請求會變得更快,加快了客戶端加載網頁的速度,提升了頁面的響應速度,也減小了冗餘數據的傳遞,節省了網絡帶寬流量,減小服務端的負擔,大大提升了網站性能。html
可是缺點也顯而易見,客戶端和服務端交互的時候,服務端的數據雖然變了,可是頁面緩存沒有改變,對於相同的url,ajax提交過去之後,瀏覽器是從緩存中拿數據,這種狀況確定是不被容許的。前端
那麼何時會觸發緩存呢,在這以前先說一下緩存機制吧。java
緩存通常分爲強制緩存和協商緩存,接下來將分別介紹一下這兩個緩存機制。ajax
就是緩存中已經有了請求數據的時候,客戶端直接從緩存中獲取數據,只有當緩存中沒有請求數據的時候,客戶端纔會從服務端拿取數據。算法
也成爲對比緩存,就是說客戶端會從緩存中獲取到一個緩存數據的標識,根據這個標識會請求服務端驗證是否失效,若是沒有失效,服務端會返回304,這時候客戶端就直接從緩存中取數據,若是失效了,服務端會返回新的數據。瀏覽器
這兩種緩存機制能夠同時存在,不過強制緩存的優先級高於協商緩存。緩存
如今咱們簡單的瞭解了一下緩存機制的原理,該說一下何時會觸發緩存,服務端是如何判斷緩存是否失效呢?你們都知道,發送請求的時候會有請求數據和響應數據,這個被稱爲報文,報文中包含首部header和主體部分body。與緩存相關的規則信息就包含在header中。body中的內容就是http請求真正要傳輸的數據。舉個http報文的頭部例子服務器
如今咱們對報文中出現的與緩存有關的信息分析一下
服務器響應的header中會用兩個字段來代表,Expires和Cache-Control。
Expires的值是服務端返回的數據到期時間。當再次請求時的請求時間小於返回的此時間,則直接使用緩存數據,可是由於客戶端和服務端的時間可能有偏差,因此這個緩存命中可能會有偏差,另外一方面,expires是http1.0的產物,因此如今大多數都使用Cache-Control
Cache-Control有不少產物,不一樣的屬性表明的意義不一樣。
private: 客戶端能夠緩存
public: 客戶端和服務器能夠緩存
max-age=t:緩存內容在t秒後失效
no-cache:須要使用協商緩存來驗證緩存數據
no-store:全部內容不使用緩存
協商緩存須要判斷是否能夠用緩存,瀏覽器第一次請求數據的時候,服務器會將緩存標識與數據一塊兒響應給客戶端,客戶端將他們備份到緩存中,再次請求時,客戶端會將緩存中的標識發送給服務器,服務器根據此標識判斷是否失效,若是沒有失效,服務端返回304狀態碼,瀏覽器拿到此狀態嗎就能夠直接使用緩存數據了。對於協商緩存來講,緩存標識很重要,對於理解協商緩存,這是重點。
接下來介紹一下協商緩存的緩存方案
服務端在響應請求時,會返回資源的最後修改時間
客戶端再次請求服務端的時候,請求頭會包含這個字段,後面跟着在緩存中獲取的資源的最後修改時間。服務端收到請求發現此請求頭中有If-Modified-Since字段,會與被請求資源的最後修改時間進行對比,若是一致則會返回304和響應報文頭,瀏覽器從緩存中獲取數據便可。從字面上看,就是說從某個時間節點開始看,是否被修改了,若是被修改了,就返回整個數據和200 OK,若是沒有被修改,服務端只要返回響應頭報文,304 Not Modified.
和If-Modified-Since相反,就是說從某個時間點開始看,是否沒有被修改.若是沒有被修改,就返回整個數據和200 OK,若是被修改了,不傳輸和返回412 Precondition failed (預處理錯誤)
If-Modified-Since和If-Unmodified-Since區別就是一個是修改了返回數據一個是沒修改返回數據。
Last-Modified也有缺點,就是說服務端的資源只是改了下修改時間,可是其實裏面的內容並無改變,會由於Last-Modified發生了改變而返回整個數據,爲了解決這個問題,http1.1推出了Etag
服務端響應請求時,經過此字段告訴客戶端當前資源在服務端生成的惟一標識(生成規則由服務端決定)
再次請求服務端的時候,客戶端的請求報文頭部會包含此字段,後面的值是從緩存中獲取的標識,服務端接收到報文後發現If-None-Match則與被請求的資源的惟一標識對比。若是相同,說明資源不用修改,則響應header,客戶端直接從緩存中獲取數據,返回狀態碼304,若是不一樣,說明資源被改過,返回整個數據,200 OK。
可是實際應用中因爲Etag的計算是使用算法計算出來的,而算法會佔用服務端的資源,全部服務端的資源都是寶貴的,因此不多使用Etag。
如今順便說一下不一樣的刷新的請求執行過程哈
若是不想使用緩存怎麼辦呢,接下來講一下解決方法
<script type="text/javascript" language="javascript"> $.ajaxSetup ({ cache: false //close AJAX cache }); </script>
function loadEventInfoPage(eventId){ $.ajaxSetup ({ cache: true // AJAX cache 下面加上時間後load的頁面中的js、css圖片等都會從新加載, //加上這句action會從新加載,可是js、css、圖片等會走緩存 }); $("#showEventInfo").load(ctx + "/custEvents/viewEvent.action", {"complaint.Id":eventId, "tt":(new Date()).getTime()},function(){}) }
9.設置html的緩存
<META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache"> <META HTTP-EQUIV="Expires" CONTENT="0">