# http的缓存类型
强缓存: 浏览器直接从本地缓存中获取数据,不与服务器进行交互
协商缓存: 浏览器发送请求到服务器,服务器判定是否可以使用本地缓存
- 强缓存和协商缓存最终使用的都是本地缓存;区别在于是否与服务器进行交互
图解:
缓存相关header:
类型 | 含义 | |
---|---|---|
Expires | 响应头 | 代表该资源的过期时间,由服务器告诉浏览器 |
Cache-Control | 请求/响应头 | 缓存控制字段,精确控制缓存策略 |
If-Modified-Since | 请求头 | 资源最近修改时间,由浏览器告诉服务器 |
Last-Modified | 响应头 | 资源最近修改时间,由服务器告诉浏览器 |
If-None-Match | 请求头 | 缓存资源标识,由浏览器告诉服务器 |
Etag | 响应头 | 资源标识,由服务器告诉浏览器 |
配对使用的字段:
- If-Modified-Since 和 Last-Modified
- If-None-Match 和 Etag
# 强缓存
由Expires 和 Cache-Control两个字段来判断缓存是否过期:
1.查看缓存是否有Cache-Control的
s-maxage或max-age指令
2.如果有,使用响应报文生成时间Date + s-maxage/max-age获得过期时间,再与当前时间进行比较
3.如果没有,比较Expires的过期时间和当前时间
Cache-Control常用指令
- no-cache:含义是不使用本地缓存,需要使用协商缓存,需要先与服务器确认缓存是否可用
- no-store:禁用缓存
- public:表明其他用户也可以使用缓存,适用于公共缓存服务器的情况
- private:表明只有特定用户才能使用缓存,适用于公共缓存服务器的情况
# 协商缓存
缓存过期了,但是不知道服务器的资源是否改变,所以需要与服务器协商判断:
浏览器:
1.判断缓存是否有ETag或者Last-Modified字段
2.如果有,就发起一个http请求,在请求头中添加If-None-Match(如果ETag存在的话)
和If-Modified-Since(如果Last-Modified存在)字段
3.如果没有,发起一个http请求,服务器直接返回资源
服务器:
1.浏览器如果同时发送了If-None-Match和If-Modified-Since字段,服务器只要比对
If-None-Match和ETag的内容是否一致即可
2.如果一致,服务器认为缓存可用,返回304状态码,浏览器直接读取本地缓存
3.如果不一致,服务器返回其他状态码,并返回所请求资源
If-None-Match和ETag
这两个值都是服务器为每份资源分配的唯一标识字符串
- 浏览器首次请求资源,服务器响应时会在响应报文头加入ETag字段。资源更新ETag值也会更新
- 浏览器再次请求资源,就会带上If-None-Match字段,它的值就是上次响应报文的ETag
- 服务器进行If-None-Match和ETag的比对......
If-Modified-Since和Last-Modified
这两个值都是GMT格式的时间字符串
- 浏览器首次请求资源,服务器响应时会在响应报文头加入Last-Modified字段,表示最后一次修改时间
- 浏览器再次请求资源,就会带上If-Modified-Since,它的值就是上次响应报文的Last-Modified
- 服务器进行If-Modified-Since和Last-Modified的比对.....
但是与ETag不同的是:比对结果是资源未更新可以使用本地缓存到时候,响应头不会添加Last-Modified字段
ETag对比Last-Modified的优点
主要是能解决几个Last-Modified难以解决的问题:
- If-Modified-Since的时间粒度是秒级的,如果文件是频繁修改的话,无法精准判断
- 有些文件只改了修改时间,却没改内容
- 有些服务器不支持精确获取文件最后的修改时间
Last-Modified和ETag是可以一起使用的,但是服务器优先验证ETag
← HTTP进化史 HTTP和HTTPS区别 →