前言:好久没写博客了,今天早上闲着没事重新看了下http的304缓存机制。下面我就简单的讲下我的理解吧。

描述:首先我们先明白一点什么是状态码。对于我们开发来说,大家一说起http状态码,都能随口说几个。比如:200,404,500等等吧,这些我们常见的。下面我给大家找了一张状态码的详细介绍图(只截了几个大家都常用的)。更为详细的的可以看这个链接。

链接:HTTP 状态码 | 菜鸟教程

正文: 
好了看完这些状态码,简单的了解后,言归正传。什么是304状态码呢。仔细的同学同学应该看到我上面的截图有304简单的介绍了。

304状态码:用我的理解来说,它就是一个客户端和服务端交互时,服务端反馈给客户端的一个是否采用缓存的一个状态标识。

作用:用于判断请求的服务资源是否更新,是否从缓存中读取数据,好处是节省带宽,加快响应速度。

到这里可能大家想304状态码和缓存有啥关系呢。

提到缓存。我们想想什么是缓存呢,我们常用的缓存又有哪些呢。

作为前端常用的缓存无非就是localStorage、cookie、sessionStorage这三个吧。最最为常用的就是localStorage。

大家用缓存的时候有没有想过缓存的作用是啥?

1、减少不必要的请求。利用本地存储加快页面渲染

2、节省带宽,给其他请求腾出请求空间。

3、避免页面刷新所用数据丢失(现在一般都会重新请求)

4、跨页面使用所用数据(现在可以用vuex/redux)

说到这里304缓存会不会有着相似的作用呢?

其实大部分缓存机制都有上面第一条和第二条特征,304机制也不例外。

说到这里什么是304状态码,什么是缓存以及它的作用大概心里都有大概的概念了吧。

接下来进入到304缓存机制它是具体实现过程是怎样的呢。听我给你慢慢吹啊。

咳咳咳:重要知识点来了。

大家有没有注意过我们发起请求时请求报文和服务端响应报文里的东西(请求报文包含三部分:请求行、请求头、请求体,响应报文包含:起始行、响应头、空行和响应体。这里我就不做多介绍了,大家可以百度查下)。

第一次请求的时候,往往会给服务端发送请求参数,请求方式等,之后等待服务端给我们响应。如果服务端设置了缓存机制那么在响应头里面通常会多出下面这几个东西(图片是从网上偷来的,自己偷个懒)

Status Code:响应状态码(下面不做介绍)

cache-control:强缓存(max-age="设置缓存的时间")

 etag:每个文件有一个,改动文件了就变了,就是个文件hash,每个文件唯一

last-modified:文件的修改时间,精确到秒。

If-Modified-Since:请求时会带上的一个时间与last-modified保持一致。

那么这些东西有什么用呢:

cache-control:max-age="xxxx"算是强缓存的一个标志。强缓存(max-age="设置缓存的时间")。意思就是只要时间没超时,就会在请求的时使用缓存的文件,不会重新请求资源。

cache-control:对应的值如下:

no-cache、no-store、public、private、max-age

 etag:"xxxx'和last-modified,If-Modified-Since是协商缓存的标志。

协商缓存涉及到这几个字段:Etag搭配If-None-Match、Last-Modified搭配If-Modified-Since。

etag的算法和资源内容有关。服务端会根据资源的内容生成一个唯一的etage.当我们修改资源时,资源内容改变会重新生成etag。

last-modified值是第一次请求发生时的时间戳,它会随着响应头返回,再次请求的时候请求头会携带上If-Modified-Since,该字段的值是上一次请求的last-modified的值.目的是让服务器知道上一次请求的时间,对比该资源在服务器上最后一次修改的时间,判断在这段时间内资源是否发生了改变

当我们请求一次资源后,浏览器会通过响应头返回一个etag值.再次请求资源时,http的请求头会携带一个if-None-Match字段,该字段的值就是etag的值.目的是为了给服务器做对比。

服务端设置协商缓存,在请求时如果文件没有更新,也就是说etag没有改变,就会返回304。每次请求返回来 response header 中的 etag和 last-modified,在下次请求时在 request header 会带上If-Modified-Since(last-modified对应)和etag,服务端把你带过来的标识进行对比,然后判断资源是否更改了,如果更改就直接返回新的资源,和更新对应的response header的标识etag、last-modified。如果资源没有变,那就不变etag、last-modified,这时候对客户端来说,每次请求都是要进行协商缓存了。

既然有了last-modified,为什么还要用etag呢。当我们修改文件的速度过快时(比如花了 100ms 完成了改动),由于 If-Modified-Since 只能检查到以秒为最小计量单位的时间差,所以它是感知不到这个改动的——该重新请求的时候,反而没有重新请求了。etag每当文件修改时就会重新生成一个新的hash值,解决了last-modified问题。

其实协商缓存机制粗暴来说就是304缓存机制!

总之一句话吧。

在我们第二次进行请求时,我们的请求会带上这些东西去服务端,服务端来判断是否读取的缓存文件,如果缓存时间有效,就直接从缓存读取文件。一般是强缓存优先(不要轻易设置强缓存)。

协商缓存的流程图:(也是偷来的,嘻嘻)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐