前言
浏览器缓存有两种:强制缓存和协商缓存
浏览器第一次发送http请求
结论:
浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中
强制缓存
强制缓存三种情况:不存在强制缓存,存在强制缓存但是已失效,存在强制缓存且有效
①不存在强制缓存
②存在强制缓存但是已失效
③存在强制缓存且有效
看完上面三张图,大家有没有疑问,就是我是怎么知道有没有缓存,然后缓存是否失效的呢?
这里就涉及到了一些缓存标识:Expires和Cache-Control【这里通过network看看】
Expires是HTTP/1.0控制网页缓存的字段;其字段内容是到期时间。这个到期时间是有bug的。因为我们缓存的是服务器时间,但是比对的时候是使用客户端时间,这样服务器时间和客户端时间可能有时区差异,导致缓存失效。
Cache-Control是HTTP/1.1控制网页缓存的字段;其字段内容是如下:
public:所有内容都将被缓存(客户端和代理服务器都可缓存)
private:所有内容只有客户端可以缓存,Cache-Control的默认取值
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定【使用缓存,但是需要经过协商缓存】
no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存【完全不缓存】
max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效【使用相对时间】
Cache-Control 优先级高于Expires
在network中,我们可能看到size是这样的(打开一个网站,然后刷新一下)
内存缓存(from memory cache)
硬盘缓存(from disk cache)
通过这个字样,我们知道请求数据是直接从缓存中取得的
协商缓存
包括两种情况:
1.协商成功
2.协商失败
那怎么判断协商缓存是否成功呢?【打开network看看】
Last-Modified / If-Modified-Since:表示文件什么时间修改的
Etag / If-None-Match: 由资源的内容而生产的唯一标识符
客户端存的是:If-Modified-Since 和 If-None-Match
服务器端的是:Last-Modified 和 Etag
然后由服务器端去成对匹配,一致的话就直接协商成功,否则协商失败!!!
其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。原因有三:
①一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候,我们并不希望客户端认为这个文件被修改了,而重新 get
②某些文件修改非常频繁,比如在秒以下的时间内进行修改(比方说 1s 内修改了 N 次),If-Modified-Since能检查到的粒度时 s 级的,这种修改无法判断
③某些服务器不能精确得到的文件的最后修改时间
最后总结:
1.强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match)
2.协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;若协商缓存生效则返回304,继续使用缓存
更多学习视频学习资料请参考:B站搜索“我们一起学前端”