網頁緩存 cache 二三事

前言

一個網頁是如何在瀏覽器上進行緩存的,其中涉及了哪些機制,有哪些技術能夠採用,如何才能最大化利用緩存.我的以爲這些知識點都是一個前端工程師必須瞭解的.曾經在面試的時候被問過一個問題,"有沒有不返回304,同時又使用了緩存的狀況?".當時由於對緩存機制瞭解不深,因此答不上來.下面我總結一下這方面的知識.javascript

經過 HTTP 報頭

Cache-Control,Expires(響應報頭)

這兩個響應報頭是瀏覽器緩存機制的第一道坎.當你發起一個 GET 請求時,服務器返回的響應報頭裏含有這兩個報頭,那麼你下一次發起請求時(以某種方式, F5刷新除外),在你設置的資源過時時間前瀏覽器都不會再次請求服務器,而是直接使用已經緩存的版本.而且 status code 是200.這也是我上面說的不是隻有返回了304纔會使用緩存html

clipboard.png
在 chrome 裏咱們能夠清楚的看到 status code 旁邊寫的是(from cache).響應報頭大體的形式也就是像上面那張圖同樣.前端

Last-Modified,ETag(響應報頭);If-Modified-Since,If-None-Match(請求報頭)

這幾個報頭能夠說是瀏覽器緩存機制裏的第二道坎.當你請求某個資源時,如上面的圖,響應報頭會設置 Last-Modified 和 ETag,Last-Modified 是這個資源的最後修改時間, ETag 是該資源的惟一標識符.這兩個值會在你再一次請求該資源時以 If-Modified-Since 和 If-None-Match 的形式附在請求頭裏發給服務器由服務器判讀該資源是否過時.若是沒過時,返回304,若是過時了,返回帶有響應主體也就是 content而且status code爲200的響應.請求報頭大體以下.這個過程稱爲服務器再認證.html5

clipboard.png

這兩種報頭的做用區間

clipboard.png
借用一張簡潔的圖來展現它們的做用區間的區別java

GET與 POST

只有GET請求才會觸發瀏覽器的緩存機制.這也是 GET和 POST 的區別之一. GET 的目的應該是請求資源而且不會對服務器上的數據產生改動,是冪等的.而 POST 的目的就是爲了修改數據.因此對於一些GET 方法的Ajax也能夠使用響應報頭的方法進行緩存, jQuery 裏的 ajax 方法裏的 cache=false 就只對 GET 方法有效,原理是在 url 後加上一個時間戳相似於 http://www.test.com?a=b_201510300000,以防止瀏覽器緩存請求.web

經過 manifest(html5)

manifest 是 一種新的緩存方式,經過 manifest 可讓網頁離線使用.下面我總結下在使用 manifest 的時候一些要注意的地方,應該工做上沒有使用 manifest 的場景,因此不作過多的深刻面試

  1. manifest文件 的 content-type必須是'text/cache-manifest',否則瀏覽器會不識別這是緩存文件.ajax

  2. 引入 manifest 的方式是<html lang="en" manifest="hello.manifest">,默認的引入的 html 文件也會被緩存.chrome

  3. manifest 文件的格式相似瀏覽器

CACHE MANIFEST
bundle.js

4.一旦瀏覽器緩存成功後,下一次瀏覽器會先使用緩存的文件,而後再發請求檢查 manifest 文件是否有變化.因此在下次打開網頁前,用戶看到的仍是舊的文件.你能夠使用 window.applicationCache 來控制當發現 manifest 文件過時後自動刷新,這樣來保證用戶能看到新的內容.
5.manifest 文件的檢查是根據相似於文件 md5的方式來檢查的,也就是說若是你在 manifest 文件里加了一個新空行,瀏覽器也會認爲 manifest 文件有更新,而後從新下載緩存文件以備下次使用.

經過 webStorageApi(html5)

webStorageApi 我主要講一下 localStorage, 由於在工做中有使用場景.在開發新後臺主頁面的時候,左側是一個很長的多級菜單,右面是 主內容.大概是這樣

圖片描述
當左側菜單拉長時,點擊連接跳到新頁面,這時左側菜單的滑動條也要保持在上個頁面的滑動位置,這時能夠監聽點擊菜單事件,經過 localStorage 來保存滑動條高度

if(target.attr('href') !== "javascript:void(0);"){
        if(window.localStorage){
            localStorage.setItem("siteScroll", scrollTop);
        }
    }else{
        $('.nav-secondary').scrollTop(target.offset().top - menuOffsetTop);
    }

下次頁面打開的時候再獲取並設置滑動條的位置

if(window.localStorage){
        var scrollTop = localStorage.getItem("siteScroll");
        $('.nav-secondary').scrollTop(scrollTop);
    }

因本人水平有限,總結過程當中不免出錯,還望你們可以指出,謝謝!

查閱應用瞭如下書籍和內容

http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/html5高級程序設計

相關文章
相關標籤/搜索