网页缓存 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高级程序设计

相关文章
相关标签/搜索