遊覽器緩存問題

遊覽器緩存問題:

首先,一個返回200的請求能夠來自遊覽器緩存,也能夠來自服務器,具體是哪一個,對於Chrome來講,要看network裏的Size頁面,是否有「from cache」說明.
一樣的,對於一個Request Headers 中有 Cache-Control: no-cache 字段的請求,也不能判斷它來自緩存仍是服務器。這個字段出如今Request Headers的意義以下:web

Cache-Control: no-cache is generally used in a request header (sent from web browser to server) to force validation of the resource in the intermediate proxies. If the client doesn't send this request to the server, intermediate proxies will return a copy of the content if it is fresh (has not expired according to Expire or max-age fields). Cache-Control directs these proxies to revalidate the copy even if it is fresh.ajax

就是爲了確保本次請求能獲得服務器上的最新資源(注意,即便從服務器獲得了304返回,也代表已經獲得了服務器的最新資源)。
若是一個帶有Cache-Control: no-cache的請求被緩存了,當它被從緩存讀出後,仍然帶有相應的Cache-Control: no-cache 字段,這時,已經不能說明這個請求是服務器上的最新資源了,仍是要看遊覽器有沒有註明這個請求是 「from cache」的。chrome

即便是「from cache」也有2種效果:一種是200的「from cache」,這種就是直接從遊覽器的緩存中讀取的,不能保證和服務器上的數據同步;第二種是304的「from cache」,這種是先發送了網絡請求,從服務器獲得了確認,再從本地緩存讀取內容,能夠保證數據和服務器上的數據同步。緩存

image

從截圖能夠看出,from cache的請求用時都很短,只須要幾毫秒;而從網絡下載的,起碼要幾十毫秒。服務器

關於Cache-Control: private

Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache, such as a proxy server.網絡

其實,若是一個response的header中存在Cache-Control: private,就代表這個請求但願遊覽器使用緩存機制。框架

下面這個文章介紹了遊覽器的cache原理
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching測試

下面的文章解釋了點擊back按鈕,遊覽器會從緩存讀取內容,以及no-cache,no-store的做用:
https://stackoverflow.com/questions/29075375/cache-control-max-age-0-no-cache-but-browser-bypasses-server-query-and-hitsthis

在ASP.Net中使用下面的代碼google

context.Response.Headers.Add("Cache-Control", new string[] { "no-cache" });

設置header的方法沒法改變cache-control的值,總會被框架複寫,因此須要下面這段代碼

protected void Application_BeginRequest()
{
    Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
}

對於採用了no-cache 設置的請求,遊覽器的前進和後退按鈕仍是會從cache中讀取,由於前進和後退是遊覽器history功能的一部分,history的目的就是把用戶上次看到的東西還原給用戶。
可是,若是新建遊覽頁(重不重啓遊覽器都同樣),再訪問一樣的網頁,private 和 no-cache的請求產生的效果就不一樣了,no-cache 的請求會向服務器發送請求 而 private的請求 卻直接被從cache中讀出(chorme 和 IE相同)。參見下面2附圖:

1.private

image

2.no-cache

image

在地址欄點擊回車,不一樣的遊覽器表現不一樣。對於chrome 68.0.3440.84,一個private的請求也會向服務器校驗,可是IE 11.165.17134.0不會,直接從cache中讀取。其實這樣的話,對於IE 11.165.17134.0 遊覽器,private就是一個十分很差的設置了,用戶在遊覽器地址欄中重複回車,數據都沒法刷新,只能經過刷新按鈕才能刷新出新數據,十分不友好。因此若是程序是主要對IE 11.165.17134.0用戶使用的,最好不用private,應該用 no-cache。no-cache 只是多了304的校驗過程,對客戶端來講,並不會浪費許多流量,一個304的返回每每不到1KB,可是多餘的請求,會對服務器形成壓力,這樣就要根據具體的狀況做出取捨了。

經過測試,還發如今IE 11.0.9600 上,在地址欄點擊回車的效果和上面的chrome的效果同樣,會像服務器發出請求。因此,若是確實但願某個請求被遊覽器cache,就應該使用 max-age = xxxx 這種屬性,IE就會把它緩存。

==遇到緩存問題,最好要到客戶的客戶端版本號,爭取在相同環境下測試,經過更改服務器返回的response header中的cache-control字段,調整出客戶須要的效果。==


用chrome測試時,經過ctrl+F5刷新,request header中的cache-control是no-cache,經過F5或在地址欄敲入回車,header中的cache-control是max-age = 0。對於同一個遊覽器,發出的全部普通request(不是ajax),都有這個現象,它是跟遊覽器的實現邏輯有關的。

下面這個連接說明了 max-age = 0 和no-cache的區別
https://stackoverflow.com/questions/1046966/whats-the-difference-between-cache-control-max-age-0-and-no-cache


另外,目前就觀察來看,遊覽器不緩存由Ajax發出的請求(就是使用XMLHttpRequest對象),只緩存剩下的普通請求。

IE遊覽器的調試狀態的Network標籤中有個按鈕,叫作「Always refresh from server」,點擊後,全部請求徹底忽略本地緩存,調試的時候記得關閉。

相關文章
相關標籤/搜索