HTTP缓存机制
简介
一个http请求包含了请求、响应2部分;这2部分又包含:头部、主体。
客户端请求
请求头——————附加信息
请求体——————正文
服务器响应
响应头——————附加信息;与缓存相关的规则信息,均包含在header中
响应体——————正文
流程
缓存的分类
根据是否需要请求服务端来分类可以分为:强制缓存、对比缓存
强制缓存:在有缓存且缓存未失效的情况下,直接读取缓存数据库的缓存。
对比缓存:在有缓存且缓存失效情况下,通过表示询问服务端,是否使用缓存。
总结:强制和对比缓存的区别是 是否使用缓存的决定权归属于谁?强制缓存是归属于浏览器;对比缓存是先归属于 浏览器、再归属于服务器。
强制缓存
强制缓存是可以直接使用缓存,但是什么时候不使用缓存?
在没有缓存数据的时候,浏览器向服务器请求数据时,服务器会将数据和缓存规则一并返回,缓存规则信息包含在响应header中。
在响应头header中包含2个字段表示失效规则:Expires/Cache-Control
Expires
HTTP 1.0中使用的,值是时间戳;因为前后端时间戳误差的问题,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。
Cache-Control
HTTP 1.1中使用,现在默认浏览器均默认使用这个参数。
Cache-Control常见取值:
public 浏览器、代理均可缓存
private 浏览器可以缓存
max-age=xxx 设置过期时间
no-cache 需要使用对比缓存
no-store 不缓存任何资源
举个例子:如下图
Cache-Control的值为:max-age=10,也就是10s内,直接使用缓存。
这是服务端代码:
客户端代码:
浏览器展示:
第一次请求
第二次请求
10后再请求
对比缓存
浏览器第一次请求时,服务器会将 缓存标识和数据一并发送过来,客户端将缓存标识和数据一并存储在缓存数据库中。
第二次请求时,客户端会将缓存表示发送给服务端,服务端根据缓存表示来判断:
若需要更新,则返回数据给客户端,状态码为200
若不需更新,则返回状态码为304,客户端使用缓存
对于对比缓存的缓存标识来说,在请求header和响应header中传递。
缓存标识
Last-modified / If-modified-Since :第一次访问的 缓存标识 和第二次访问的 缓存标识;使用修改时间作为值。
Etag / If-None-Match:第一次访问的 缓存标识 和第二次访问的 缓存标识;使用唯一标识(唯一标识后端定义规则生成)作为值。 (优先级高于 Last-Modified / If-Modified-Since )
Last-modified
If-modified-Since
Etag
服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)
If-None-Match
再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。
服务器收到请求后发现有头If-None-Match 则与被请求资源的唯一标识进行比对,
不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;
相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
总结:Last-modified是第一次请求的缓存标识,If-Modified-Sine是二次之后的请求标识;二次请求资源,当修改时间发生变化,则判定资源修改,则响应整片资源;反之,返回304状态码,客户端使用缓存。
Etag是第一次请求的缓存标识,If-None-Match是二次请求的缓存标识;二次请求资源,当唯一表示发生变化,判定资源修改,则响应整片资源;反之,返回304状态码,客户端使用缓存。
总结
1.按照是否需要重新请求,缓存分为 对比缓存和强制缓存。
2.目前浏览器都是HTTP 1.1的 Cache-Control指定缓存类型,常见的几种值:public(客户端和代理缓存)、private(客户端缓存)、max-age(指定缓存时长)、no-cache(对比缓存)、no-store(不缓存)
3.对比缓存是服务器通过缓存标识来决定是否缓存;缓存标识有2种:Last-Modified / If-Modified-Since 和 Etag / If-None-Match;后者的优先级高于前者。
一个完整的请求流程
参考文献
https://www.cnblogs.com/chenqf/p/6386163.html