理解浏览器缓存以及304状态码

过去没太研究过HTTP,最近有空,看了一些。本文主要讨论浏览器缓存以及304状态码的一些知识,在这里作一个分享,这里先上一张HTTP请求流程图:html

Alt text

1、详细讨论

一、是否禁止缓存

禁止缓存指的是缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。segmentfault

在请求头中,Cache-Control: no-storePragma: no-cache均可以禁止缓存,浏览器

但二者也有区别,Pragma: no-cache能够兼容http 1.0 ,而Cache-Control: no-storehttp 1.1提供的。所以,Pragma: no-cache能够应用到http 1.0http 1.1,而Cache-Control: no-store只能应用于http 1.1缓存

二、是否检查本地副本是否过时

是否检查本地版本是否过时主要由Cache-Controno-cachemust-revalidate这两个可选值控制,其中:服务器

  • no-cache: 告诉浏览器、缓存服务器,无论本地副本是否过时,使用资源副本前,必定要到源服务器进行副本有效性校验。
  • must-revalidate:告诉浏览器、缓存服务器,本地副本过时前,可使用本地副本;本地副本一旦过时,必须去源服务器进行有效性校验。

三、本地副本是否过时

想要知道本地副本是否过时,咱们就须要了解缓存的过时机制网站

(1)、过时机制中,最重要的指令是 max-age=<seconds>,它表示资源可以被缓的最大时间;它一般会和must-revalidate一块儿使用,使用起来就像下面这样:spa

Cache-Control: max-age=60, must-revalidate
复制代码

(2)、若是不含有max-age属性,则会去查看是否包含Expires属性,,经过比较Expires的值和头里面Date属性的值来判断是否缓存还有效。代理

Alt text

(3)、若是 max-ageexpires 属性都没有,找找头里的 Last-Modified 信息。若是有,缓存的寿命就等于头里面 Date的值减去Last-Modified的值除以10(注:根据rfc2626其实也就是乘以10%)。code

Alt text

四、若是本地副本没有过时

若是本地副本没有过时,则会直接重缓存中读取资源,并返回200状态码。cdn

Alt text

五、若是本地副本过时

若是本地副本过时,则会进行到源服务器进行有效性校验的前期准备

首先,会在请求头里寻找If-None-Match字段,其值为服务器上次返回的ETag响应头的值:

Alt text

Alt text

若是请求头里没有If-None-Match字段,则会在请求头中寻找If-Modified-Since字段,其值为服务器上次返回的Last-Modified响应头中的日期值:

Alt text

Alt text

若是If-None-MatchIf-Modified-Since都没有,则会直接向服务器请求数据。

六、到源服务器进行有效性校验

若是请求头中带有If-None-MatchIf-Modified-Since,则会到源服务器进行有效性校验,若是源服务器资源没有变化,则会返回304;若是有变化,则返回200;

七、上述的一些流程还能够用下图来表示

Alt text

2、补充

私有缓存和公共缓存

Cache-Control还有两个值:privatepublic,其中:

public 指令表示该响应能够被任何中间人(好比中间代理、CDN等)缓存。若指定了 public ,则一些一般不被中间人缓存的页面(由于默认是 private)(好比 带有HTTP验证信息(账号密码)的页面 或 某些特定影响状态码的页面),将会被其缓存。

private 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。

3、参考文档

HTTP协议 MDN segmentfault网站上'赵雍'的回答 '紫云飞'的博客

原文地址 王玉略的我的网站

相关文章
相关标签/搜索