前端靜態資源的緩存和更新問題解析

瀏覽器緩存主要有兩類 
緩存協商:Last-midified ,Etag 
完全緩存:cache-control,Expires php

  緩存協商的意思是須要去服務器端詢問頁面有沒有修改過,沒有修改過則返回304直接使用緩存內容,不然返回新內容 
協商步驟: css

一、服務器發送帶Last-midified:GMTtime 頭的http responsehtml

二、瀏覽器下次請求時帶上if-modified-since:GMTtime http 請求頭html5

三、服務端用本地Last-midified時間與if-modified-since比較,計算瀏覽器數據是否過時併發送響應node

Etag的工做原理與Last-midified相似,不一樣點在於Etag的值是用戶可自定義的 web

  完全緩存的意思是在緩存失效以前再也不須要跟服務器交互 apache

經常使用的是Expires,Expires的值是一個絕對時間,由服務器產生 這兒存在一個問題,就是服務器的時間可能給客戶端的時間不一致致使緩存時間的誤差 api

要解決這個問題就要使用cache-control,它保存的是一個相對瀏覽器的時間 瀏覽器

若是同時存在cache-control和Expires怎麼辦呢? 瀏覽器老是優先使用cache-control,若是沒有cache-control才考慮Expires 緩存

expire:
若是apache開啓了expire模塊, 當瀏覽器發送該資源請求的時候, apache返回資源的同時,會返回一個名爲expire的http頭,expire頭的內容是一個時間值, 這一個值就是資源在本地的過時時間, 這個值會存在本地.
也就是說,在本地緩存階段,在本地找到了一個對應的資源值,並且當前時間還沒超過資源的過時時間, 那麼就直接使用這一個資源,不會發送http請求.

cache-control:
cache-control是http協議中經常使用的頭部之一,顧名思義, 他是負責控制頁面的緩存機制,若是該頭部指示緩存, 緩存的內容也會存在本地, 操做流程和expire類似,但也有不一樣的地方, cache-control有更多的選項, 並且也有更多的處理方式.

if-modified-since 和 last-modified:
當apache接收到一個資源請求(假設是用戶是第一次訪問,沒有任何緩存), 服務器返回資源的同時,還會發送一個last-modified的http響應頭, last-modified響應頭的內容值是該資源在服務器上最後修改的時間.瀏覽器接受到這個http頭後,會
把其內容值和資源同時保存起來.
當用戶第二發送資源請求(假設這裏expire沒有生效或者已通過期), 瀏覽器在本地找到了一個相同的資源,可是不能肯定該資源是否和服務器上的同樣(有可能在兩次訪問期間,服務器上的資源已經被修改過),此時瀏覽器發送請求的時候,請求頭內會
附帶一個if-modified-since的請求頭, 這個頭部的內容就是上一次last-modified返回的值, 服務器把這個頭的值和請求資源的最後修改時間對比,若是兩個值相同,則認爲資源沒有修改,將會返回304,讓瀏覽器使用本地資源.不然服務器將返回資源,並且
返回200狀態

if-none-match 和 etag:
其實這兩個頭部和if-modified-since, last-modified的工做原理是同樣的, if-none-match做爲請求頭, etag做爲響應頭.既然工做原理同樣, 爲何etag這對頭部會出現呢?
緣由在於, last-modified請求頭的內容是以文件最後修改的時間做爲對比的,可是unix系統裏面, 文件修改的時間只保存到了秒. 若是某些應用內存在1秒內對文件作了屢次修改,這樣last-modified是不能完成比較功能的.因此要引入一個新的機制(緣由可能不止這一個);
etag的值通常由3個數值組成,資源的inode值, 最後修改時間, 資源大小,以16進制組成一個字符串, 例如:1a-182b-10f; 但這個格式不是固定的, 只要保證該值的惟一性,但不限格式.

靜態資源的更新:張雲龍老師的blog寫的很好移步這裏

 

html5離線存儲

步驟:

一、配置apache讓apache支持manifest文件

二、建立manifest文件test.manifest

1 CACHE MANIFEST  # wanz app v1     
2 # 指明緩存入口(指明須要緩存的文件)  
3 CACHE:  index.html  style.css  images/logo.png  scripts/main.js     # 如下資源必須在線訪問  
4 NETWORK:  login.php     
5 # 若是index.php沒法訪問則用404.html代替  
6 FALLBACK:  /index.php /404.html

三、關聯manifest文件到html文檔

 1 <html manifest="test.manifest"> ... </html> 

注意:#是用來註釋一行的,但它還有一個小做用,web應用的緩存只有在manifest文件被修改的狀況下才會被更新,因此若是你只是修改了被緩存的文件,那麼用戶本地的緩存仍是不會被更新的,可是你能夠經過修改manifest文件來告訴瀏覽器須要更新緩存了。利用這點,你能夠像上面的例子中那樣,寫一句這樣的註釋一個文件版本:

# wanz app v1

優勢:你能夠很明確的瞭解離線web應用的版本
   經過簡單的修改這個版本號就能夠輕易的通知瀏覽器更新
   你能夠配合JavaScript程序來完成緩存更新

CACHE:
這個是manifest文件的默認入口,在此入口以後羅列的文件 (或直接寫在CACHE MANIFEST後的文件)在它們下載到本地後會被緩存起來
NETWORK:
可選的,在此節後面所羅列的文件是須要訪問網絡的,即便用戶離線訪問了也會直接跳過緩存而訪問服務器
FALLBACK:
可選的,用來指定資源沒法訪問時的回調頁面。每一行包括兩個URI,第一個是資源文件URI,第二個是回調頁面URI。

html5緩存的更新問題:

方法有三種:

一、用戶清除了離線存儲的數據,這個不必定就是清理瀏覽器歷史記錄就能夠作到的,由於不一樣瀏覽器管理離線存儲的方式不一樣。好比Firefox的離線存儲數據要到「選項」=>「高級」=>「網絡」=>「脫機存儲」裏才能夠清除。
二、manifest文件被修改,上面說的,你修改了manifest文件裏所羅列的文件也不會更新緩存,而是要替換manifest文件//修改註釋更新# wanz app v1
三、使用JavaScript api編寫更新程序

方法12爲自動更新,方法3爲手動更新

1 var appCache = window.applicationCache;     
2 appCache.update(); // 開始更新     
3 if (appCache.status == window.applicationCache.UPDATEREADY) {    
  appCache.swapCache(); // 獲得最新版本緩存列表,而且成功下載資源,更新緩存到最新 }
相關文章
相關標籤/搜索