浏览器缓存原理

浏览器三级缓存原理

  • 先查找浏览器内存,如果内存中存在,从内存中加载;
  • 如果浏览器内存中未查找到,选择硬盘浏览器缓存文件获取,缓存文件保存在浏览器缓存目录中,也就是硬盘;
  • 如果浏览器内存中没有找到,缓存目录中也没找到,那就发送网络请求去HTTP服务器中查找;
  • 重新缓存到浏览器内存和缓存文件中
HTTP状态码及区别
状态码 浏览器Size字段显示 说明
200 memory cache 不发送http请求,资源在本地浏览器内存
200 disk cache 不发送http请求,资源在本地浏览器磁盘中
200 资源大小字节数 发送http请求,下载资源
304 资源大小字节数 发送http请求,请求值响应响应头信息,不返回资源
  • 【浏览器缓存原理】状态码示例

    浏览器缓存原理
    文章图片
    缓存1.png
  • 浏览器缓存动画示例

    缓存动画.gif
以上测试时在谷歌浏览器中测试结果,其他浏览器可能会发送http请求,然后收到304状态码。谷歌浏览器测试显示,文档类型(HTML页面)请求会带上If-Modified-Since 和 If-None-Match请求头去服务器校验一遍,如果更新重新下载,其他资源全部从浏览器缓存加载,不发送请求。
  • 其他浏览器可能都会发送请求带上If-Modified-Since 和 If-None-Match请求头,然后返回304。(IE和其他浏览器未测试)
  • 测试结果截图

    浏览器缓存原理
    文章图片
    304请求.png
浏览器缓存原理
文章图片
200-memory-cache.png 在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报有:
字段 作用 类型
Pragma no-cache 告诉浏览器忽略资源的缓存副本,每次访问都需要去服务器拉取【http1.0中存在的字段,在http1.1已被抛弃,使用Cache-Control替代,但为了做http协议的向下兼容,很多网站依旧会带上这个字段】 响应
Expires 2012 启用缓存和定义缓存时间。告诉浏览器资源缓存过期时间,如果还没过该时间点则不发请求【http1.0中存在的字段,该字段所定义的缓存时间是相对服务器上的时间而言的,如果客户端上的时间跟服务器上的时间不一致(特别是用户修改了自己电脑的系统时间),那缓存时间可能就没啥意义了。在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代】 响应
Cache-Contro no-cache(告诉浏览器忽略资源的缓存副本(请求头带的),强制每次请求直接发送给服务器,拉取资源,但不是“不缓存”)
no-store(强制缓存在任何情况下都不要保留任何副本)
max-age=秒
public(任何路径的缓存者(本地缓存、代理服务器),可以无条件的缓存资源)
private(只针对单个用户或者实体(不同用户、窗口)缓存资源)
告诉浏览器忽略资源的缓存副本,强制每次请求直接发送给服务器,拉取资源,但不是“不缓存” 请求
Last-Modified 时间 告诉浏览器这个资源最后的修改时间。服务器将资源传递给客户端时,会将资源最后更改的时间以“Last-Modified: GMT”的形式加在实体首部上一起返回给客户端【只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间】 响应
If-Modified-Since 上次请求Last-modified的值 其值为上次响应头的Last-Modified值,再次向web服务器请求时带上头If-Modified-Since。web服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),包括更新Last-Modified的值,HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304(无需包体,节省浏览),告知浏览器继续使用所保存的cache 请求
ETag 字符 告诉浏览器当前资源在服务器的唯一标识符(生成规则又服务器决定) 响应
If-None-Match 上次请求的Etag 当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match(Etag的值)。web服务器收到请求后发现有头If-None-Match则与被请求资源的相应校验串进行比对,决定返回200或304 请求
浏览器HTTP请求流程 第一次请求 浏览器缓存原理
文章图片
http请求流程.png 后面请求 浏览器缓存原理
文章图片
用户行为请求头字段有效性
用户操作 Expires/Cache-Control Last-Modified/Etag
地址栏回车 有效 有效
页面链接跳转 有效 有效
新开窗口 有效 有效
前进、后退 有效 有效
F5刷新 无效(BR重置max-age=0) 有效
ctrl+F5 无效(重置Cache-Control=no-cache) 无效(请求头丢弃该选项
不使用浏览器缓存的请求
当然并不是所有请求都能被缓存,无法被浏览器缓存的请求如下:
  • HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告诉浏览器使用浏览器缓存即meomy cache和disk cache;
    (注意是不使用本地浏览器缓存。网络请求会发出去响应状态码可能是304或者200)
  • 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的
  • 经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)
  • POST请求无法被缓存
  • HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存
参考资料
  1. http://www.cnblogs.com/520yang/articles/4807408.html 浏览器 HTTP 协议缓存机制详解
  2. https://my.oschina.net/leejun2005/blog/369148 浏览器 HTTP 协议缓存机制详解
  3. http://web.jobbole.com/82997/ 浏览器缓存机制浅析
  4. http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/ Web浏览器的缓存机制
  5. http://www.cnblogs.com/vajoy/p/5341664.html 浅谈浏览器http的缓存机制
  6. http://mp.weixin.qq.com/s/yf0pWRFM7v9Ru3D9_JhGPQ 浏览器缓存机制剖析
    7.https://www.cnblogs.com/kevingrace/p/10459429.html

    推荐阅读