http 的缓存都是从资源的第二次请求开始的,由于首次请求都是新的资源。浏览器
浏览器 http 缓存能够分为强缓存和协商缓存。缓存
强缓存和协商缓存的区别是:服务器
下表所列缓存按照优先级进行排序:代理
字段名称 | 字段分类 |
---|---|
Pragma | 请求头&响应头 |
Cache-Control | 请求头&响应头 |
Expires | 响应头 |
If-None-Match / ETag | 请求头 / 响应头 |
If-Modified-Since / Last-Modified | 请求头 / 响应头 |
强缓存在未失效的状况下(即 Cache-Control 的值没有过时或者 Expires 的缓存时间没有过时),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。强制缓存生效时,http 状态码为 200。对象
Pragma 是一个在 HTTP/1.0 中规定的通用首部,它在响应头的行为没有规范,依赖于浏览器的实现,建议只在须要兼容 HTTP/1.0 客户端的场合下应用。参数只有一个:no-cache,会通知浏览器不直接使用强缓存,由于它优先级最高,当存在时必定不会命中强缓存。排序
Cache-Control 也是 HTTP/1.1 控制浏览器缓存的主流字段,被用于在请求和响应中。请求头和相应头指令略有不一样,这里列举几个常见的指令:内存
Expires 是一个响应首部字段,它指定了一个日期/时间(值为GMT时间,即格林尼治时间),在这个时间/日期以前,缓存被认为是有效的。若是在 Cache-Control 响应头设置了 "max-age" 或者 "s-max-age" 指令,那么 Expires 头会被忽略。资源
当 Cache-Control 和 Expires 过时或者 Cache-Control 的属性设置为 no-cache 时,那么此时浏览器就会发送请求与服务器进行协商,服务器端对比判断资源是否进行了修改更新。若是资源没有修改,那么就会返回 304 状态码,告诉浏览器可使用缓存中的数据,减小服务器的数据传输压力。字符串
ETag 是一个响应首部字段,它是根据实体内容生成的一段hash字符串,标识资源的状态,由服务端产生。If-None-Match 是相应的请求头字段。当与 If-Modified-Since 一同使用的时候,If-None-Match 优先级更高hash
Last-Modified 是一个响应首部字段,包含该资源上次修改的时间。 If-Modified-Since 是相应的请求头字段。
当浏览器第一次向服务器发送请求时,会在响应头中返回协商缓存的属性:ETag 和 Last-Modified,而后浏览器在第二次发送请求的时候,会在请求头中带上与 ETag 对应的 If-Not-Match,其值就是响应头中返回的 ETag 的值,Last-Modified 对应的 If-Modified-Since。服务器在接收到这两个参数后会作比较,若是返回的是304状态码,则说明请求的资源没有修改,浏览器能够直接在缓存中取数据,不然,服务器会直接返回数据。
当浏览器触发强缓存时,咱们会看到资源会显示 from memory cache 或者 from disk cache 的字样,正常状况下,当咱们这在访问页面时,资源会从内存中加载,即 from memory cache,若是咱们关闭浏览器,而后重新打开页面,就会从磁盘加载该文件(前提是都触发了强缓存),即 from disk cache,当咱们再次刷新是,资源又会被放到内存里了。