过去没太研究过HTTP,最近有空,看了一些。本文主要讨论浏览器缓存以及304状态码的一些知识,在这里作一个分享,这里先上一张HTTP请求流程图:html
禁止缓存指的是缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。segmentfault
在请求头中,Cache-Control: no-store
与Pragma: no-cache
均可以禁止缓存,浏览器
但二者也有区别,Pragma: no-cache
能够兼容http 1.0
,而Cache-Control: no-store
是http 1.1
提供的。所以,Pragma: no-cache
能够应用到http 1.0
和http 1.1
,而Cache-Control: no-store
只能应用于http 1.1
。缓存
是否检查本地版本是否过时主要由Cache-Contro
的 no-cache
和must-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属性的值来判断是否缓存还有效。代理
(3)、若是 max-age
和 expires
属性都没有,找找头里的 Last-Modified 信息。若是有,缓存的寿命就等于头里面 Date
的值减去Last-Modified
的值除以10(注:根据rfc2626其实也就是乘以10%)。code
若是本地副本没有过时,则会直接重缓存中读取资源,并返回200状态码。cdn
若是本地副本过时,则会进行到源服务器进行有效性校验的前期准备。
首先,会在请求头里寻找If-None-Match字段,其值为服务器上次返回的ETag响应头的值:
若是请求头里没有If-None-Match字段,则会在请求头中寻找If-Modified-Since字段,其值为服务器上次返回的Last-Modified响应头中的日期值:
若是If-None-Match
与If-Modified-Since
都没有,则会直接向服务器请求数据。
若是请求头中带有If-None-Match
或If-Modified-Since
,则会到源服务器进行有效性校验,若是源服务器资源没有变化,则会返回304;若是有变化,则返回200;
在Cache-Control
还有两个值:private
与public
,其中:
public
指令表示该响应能够被任何中间人(好比中间代理、CDN等)缓存。若指定了 public
,则一些一般不被中间人缓存的页面(由于默认是 private
)(好比 带有HTTP验证信息(账号密码)的页面 或 某些特定影响状态码的页面),将会被其缓存。
而 private
则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。
HTTP协议 MDN segmentfault网站上'赵雍'的回答 '紫云飞'的博客
原文地址 王玉略的我的网站