http请求过程中缓存是如何工作的

一个一般情况下的例子:

浏览器输入url,第一次发送http请求的时候,肯定是不会有缓存这一说的,直接从服务器读取数据。
以下讨论的是第二次以后的输入相同的url,缓存是如何工作的。

1、判断是否有强制缓存

第一次返回http响应的时候, 如果响应中携带cache-control或者expires,这两个字段,
则说明这个资源是设置了强制缓存,
什么意思呢,就是第二次请求这个资源时,在浏览器端,先去判断cache-control或者expires的值,
如果成立,则直接在缓存中获取,不去发送http请求,典型代表200 OK(from memory cache)

那么是怎么进行判断的呢,
expires是http1的标准,cache-control是http1.1的标准。
expires指定资源的过期时间,浏览器第二次请求时,判断本地时间是否超过了这个过期时间,
如果没有超过,则直接从缓存中取数据,不去发送http请求到服务端,
如果超过过期时间,则发送http请求到服务端

cache-control中有个max-age指令,
expires的意思差不多,也是指定过期时间,
但是和expires不同的是,max-age指定的值,是个相对值,相对于第一次请求的时间,
也就是说浏览器第二次请求时,如果相对于第一次请求的时间,
没有超过max-age指定的时间,则直接从缓存中取数据,不去发送http请求到服务端;
浏览器第二次请求时,如果相对于第一次请求的时间,
超过max-age指定的时间,则需要发送http请求到服务端。

http响应中如果同时包括expirescache-control,两个需要都满足,才会从缓存中获取资源。
实际中,用一个就可以,cache-control的优先级高于expires
expires是个相对于服务器的绝对时间,如果把本机的时间修改了,和服务器不一致,则不准确了,推荐用cache-control就可以。

2、判断是否有协商缓存

第一次返回http响应的时候, 如果响应中携带Etag或者last-modified,这两个字段,
则也说明服务器端也希望这个资源被缓存。

那么是怎么进行缓存操作的呢
强制缓存不成功,才去判断是否有协商缓存,此时需要发送http请求,
发送http请求时,如果第一次请求返回的响应中携带Etag或者last-modified
则第二次请求头会包含if-none-match或者if-modified-since,
第一次请求返回的响应中Etag指令是响应数据的一个hash值,
第二次请求时,会将这个hash值给到if-none-match
然后在服务器端,计算数据的hash值,得出一个hash,判断这个计算出的hash与if-none-match的hash是否相等,
如果相等,则说明第二次请求的数据并没有发生变化,
服务器端会返回304响应状态码,告诉浏览器端,直接取浏览器端的缓存;
如果不相等,服务器端返回200,生成新的Etag值,返回新数据,给到浏览器。

if-modified-since的目的和Etag的目的一样,他是个相对于服务器的绝对时间,
如果把本机的时间修改了,和服务器不一致,则不准确了,,如果把本机的时间修改了,则不准确了,推荐用Etag就可以。

其他

以上是个正常流程,看一下其他的情况:
1、 第一次返回http响应的时候, cache-controlmax-age为0或者no-cache,
就是服务器端不希望浏览器直接读取缓存,而是要通过发送http请求,通过Etag或者last-modified等指令去判断是否读取缓存。
这时候要么返回200,要么返回304,不会返回200 OK(from memory cache)
意思就是怎么都要去服务器端去判断一下内容有没有更新,不允许直接读取缓存,

2、 发送http请求的时候,如果带有cache-controlmax-age为0,则为浏览器不去判断是否有缓存,直接发送http请求,
chrome刷新浏览器的时候,请求中会默认带上cache-controlmax-age为0,
这种情况就不会返回200 OK(from memory cache)

参考文献:
https://www.cnblogs.com/wonyu...

相关推荐