一个一般情况下的例子:
浏览器输入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响应中如果同时包括expires
和cache-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-control
的max-age
为0或者no-cache,就是服务器端不希望浏览器直接读取缓存,而是要通过发送http请求,通过Etag
或者last-modified
等指令去判断是否读取缓存。这时候要么返回200
,要么返回304
,不会返回200 OK(from memory cache)
,意思就是怎么都要去服务器端去判断一下内容有没有更新,不允许直接读取缓存, 2、 发送http请求的时候,如果带有cache-control
的max-age
为0,则为浏览器不去判断是否有缓存,直接发送http请求,
cache-control
的max-age
为0,这种情况就不会返回200 OK(from memory cache)
。 参考文献: