对于http缓存,之前一直只知道根据 浏览器是否向服务端发请求来确认是否使用缓存资源缓,浏览器缓存分 强制缓存 和 协商缓存 ,分别使用的字段前者是Expires和Cach-control,后者是 Etag 和 Last-modified ,但对于整个浏览器缓存过程是怎么样的 比较模糊,看了一些博客文章,和看书后算是弄懂了,精炼后总结如下:
记录下来,方面以后回顾
注:缓存一定是之前已经有请求过资源的了,否则何来 "缓存" 一说
http缓存:浏览器向服务器请求资源时,会先到达浏览器缓存,当缓存中有想要请求的资源的副本的话,就直接使用缓存里的资源,而是向原始服务器来读取这个资源
注:http 缓存只能缓存 get 方式请求的资源
http 缓存总过程
- 先强缓存,不向发请求;
- 强缓存没有命中的话 再发向服务端起请求,协商缓存;
- 服务端协商缓存命中的话,则不返回资源文件,直接让浏览器读取本地资源(状态码:304 Not Modified)
- 如果协商缓存也没命中的话,则服务端再返回资源文件(状态码:200)
http 缓存的具体过程:
- 浏览器在发起请求资源前,会根据请求头字段 Expires 和 Cach-control
判断是否命中强缓存,如果命中的话就直接读取本地缓存资源,不会向服务器发请求,且返回的状态码是200
- 如果没有命中强缓存,则浏览器会发起请求,会带一些请求头字段,服务端根据这些字段来判断是否命中协商缓存。 比如 if-none-match
和 if-modified-since,这是浏览器发给服务端的请求头字段。
if-none-match
的值:上次请求服务端返回资源的响应头字段里的Etag
的值, Etag: 服务端根据 资源文件
生成的唯一标识; 只要资源文件没变化则 Etag 值不变if-modified-since
的值: 上次服务端返回的last-modified
的值, last-modified : 响应资源在服务端最后修改的日期
- 然后服务端会判断这次请求字段的 if-none-match 和根据它请求的资源文件生产的 Etag 的值,看二者是不是相同,
或者判断
请求字段的 if-modified-since 和 服务端该资源的最后修改时间做对象,看二者是否相同。 - 相同的话说明资源没有改变过,则不会返回资源文件,而是返回304 ,表示协商缓存, 告诉浏览器直接读取它本地的缓存资源
如果不同的话
说明资源已经变化了,则会返回请求的资源文件,和状态码200 ,协商缓存失效
协商缓存两对字段的各自缺点:
-
Last-Modified / If- Modified-Since
可能有些文件会周期性地改变日期,但是内容其实没变,这个情况下希望继续使用缓存,但是该字段对只判断 资源最后修改时间,只要这个日期改变了就不使用缓存,而不管资源内容是否真的改变了
-
Etag / If-None-Match
-- Etag 是服务器针对请求的资源文件生成的唯一标识,所以和修改时间无关,只要文件内容没变化,则Etag值不变,克服了 Last-Modified / If- Modified-Since 的缺点
-- Etag 缺点:不适用于 分布式系统 ,因为每个服务器上的 Etag 值不同
强制缓存的两个缓存字段
Expires:
设的是资源的过期时间,浏览器判断这次请求的时候是不是超过这个日期
没超的话就直接读取缓存中的资源,不向服务器发请求
Cach-Control:
缓存控制 有几个值
-
Max-Age:是相对时间, 是上次请求开始到资源过期之间的时间间隔,可以看做是设定了缓存有效期的长短
没超的话就直接读取缓存中的资源,不向服务器发请求 - No-Cache: 会强制 浏览器每次都直接向服务端请求,即跳过强制缓存,直接进行协商缓存(注:而不是说不用缓存)
- No-Store: 这个才是表明 禁用一切缓存 ,即每次请求都是服务端直接返回资源文件,不去判断也不去读取缓存资源
http缓存 的好处
-
加快了客户端访问页面的速度
-
如果是强制缓存,可以减少与服务器的交互,减小服务器的负担
网站性能方面谈 http缓存
由于协商缓存还是需要和服务器交互,所以
尽量使用强制缓存,而不使用协商缓存
如何使用 http缓存
- HTML 页面
在<head>
标签 里加入<meta>
标签,并加入相关参数(比如expires, cache-control)的设置(通过http-equiv
和content
)
栗子:
<meta http-equiv = "expires" content = "0"> - 静态资源(比如CSS文件,图片等)
静态资源的缓存的设置一般都是在 web服务器上(nginx,apache)进行的
网友评论