HTTP 的缓存机制

目录

一、前言

1.1 浏览器发送请求和本地缓存的关系

1.2 HTTP中缓存的类型

1.2.1  强制缓存

1.2.2  对比缓存

1.2.3  总结强制缓存和对比缓存

二、 Expires字段

三、cache-control字段可选的值

3.1  在响应(response)中使用 cache-control时,它可选的值有:

3.2  在请求(request)中使用 cache-control时,它可选的值有:

3.3 设置了 no-cache时,判断资源是否更新过的机制

3.3.1  Last-Modified 

3.3.2  Etag

3.3.3 Last-Modified 和 Etag的区别


一、前言

我们在用http访问时,会先发送一个请求,之后服务器返回一个应答,在chrome浏览器中,F12 进入开发者模式后,进入随意一个网站,会出现如下过程:

第一部分General是概要,包含请求地址,请求方式,状态码,服务器地址等等。

第二部分是应答头部(response),是服务器返回的。

第三部分是请求头部(request),是客户端发送的。

我们可以看到在response和request中都出现cache-control,cache-control 是控制本地缓存的字段。

 

1.1 浏览器发送请求和本地缓存的关系

如下图:

当浏览器发送请求后,先去本地缓存找到,若本地缓存有要请求的资源,则直接返回,若没有的话,就去代理的缓存中找,找到(即命中)则返回,不命中才会去服务器中找。

 

1.2 HTTP中缓存的类型

根据是否需要重新向服务器发起请求来分类的话,HTTP的缓存可以分为:强制缓存和对比缓存两种。

假设浏览器有一个缓存数据库用于本地缓存。

1.2.1  强制缓存

强制缓存可以理解为无须验证的缓存策略。

缓存命中的情况下:

若浏览器本地缓存中有客户端请求的资源,且资源尚未失效,那么则直接取用缓存中的资源。

缓存未命中:

若请求的资源在缓存中已经失效,那么就去服务器上找。然后把服务器返回的资源存到本地缓存中。

 

1.2.2  对比缓存

缓存的资源到期了,并不意味着资源内容发生了改变,如果和服务器上的资源没有差异,实际上没有必要再次请求。客户端和服务器端通过某种验证机制验证当前请求资源是否可以使用缓存。

浏览器第一次请求数据之后会将数据和响应头部的缓存标识存储起来。再次请求时会带上存储的头部字段,服务器端验证是否可用。如果返回 304 Not Modified,代表资源没有发生改变可以使用缓存的数据,获取新的过期时间。反之返回 200 就相当于重新请求了一遍资源并替换旧资源。

 

使用对比缓存命中:

对比缓存:从本地缓存中获取数据后,会把数据标识(Etag或Last-Modified,下面会详细讲) 送到服务器处验证是否更改过。若没有更改过,则直接取用本地缓存的数据,若更改过,则服务器返回最新的。

未命中:

有同学可能会问,基于对比缓存的流程下,不管是否使用缓存,都需要向服务器发送请求,那么还用缓存干什么?

我们看一下,第一次请求时,由于没有缓存,因此直接向服务器获取资源,返回的数据大小为5.6 KB

第一次请求资源:

然后再次请求同样的资源,可以看到下图,服务器返回的数据大小少了很多。原因是第一次服务器返回的是资源+标识,第二次服务器返回的仅仅是标识而已。

第二次请求资源

1.2.3  总结强制缓存和对比缓存

  • HTTP缓存主要分强制缓存和对比缓存
  • 强制缓存的HTTP相关头部Cache-Control,Exipres(HTTP1.0),浏览器直接读本地缓存,不会再跟服务器端交互,状态码200。
  • 对比缓存的HTTP相关头部Last-Modified / If-Modified-Since, Etag / If-None-Match (优先级比Last-Modified / If-Modified-Since高),每次请求需要让服务器判断一下资源是否更新过,从而决定浏览器是否使用缓存,如果是,则返回304,否则重新完整响应。

二、 Expires字段

Expires是HTTP1.0的产物,现在浏览器默认使用HTTP1.1 ,所以expires的作用基本上忽略。但是很多网站还是对它做了兼容。

它的值为 到期时间 。即下一次请求时,请求时间小于服务器返回的到期时间,说明缓存没过期,那么直接使用缓存数据。

但有一个问题是,由于缓存时间是服务器生成的,如果客户端时间和服务端不一致,这就会导致缓存命中的误差。

在HTTP1.1 中,Expires被 Cache-control代替。

三、cache-control字段可选的值

3.1  在响应(response)中使用 cache-control时,它可选的值有:

几个着重的值:

  1. public:http通信时,包括请求的发送方(浏览器) 、代理缓存服务器都可以进行缓存。
  2. private:只允许请求的发起方(浏览器)进行缓存。
  3. no-store:任何地方都不可以缓存。
  4. no-cache:在缓存有效的时间内,若浏览器对相同的资源发起请求,会先去服务器询问资源是否修改过,若资源没有被修改过,服务器响应304(Not Modiied),浏览器得到304响应后,判断缓存可以使用,就会直接使用缓存。如果缓存更新过,就返回200,浏览器使用返回的资源。
  5. max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;

3.2  在请求(request)中使用 cache-control时,它可选的值有:

 

3.3 设置了 no-cache时,判断资源是否更新过的机制

3.3.1  Last-Modified 

Last-Modified 配合 If-Modified-Since(或 If-Unmodified-Since)使用:

通过对比资源上次修改的时间验证是否使用缓存。

步骤:

1. 浏览器第一次对资源发起请求时,服务器会设置响应(response)报文 头信息里的 头部 Last-Modified 。

2. 当浏览器再次对相同的资源发起请求时,浏览器会设置请求(request)的头部,设置 If-Modified-Since(或 If-Unmodified-Since) 为之前接收的 Last-Modified的值。这样,服务器每次取得浏览器发来的request头部信息中的 If-Modified-Since(或 If-Unmodified-Since) ,然后与文件的修改时间对比,如果相同,则返回状态码304 (Not Modified),然后浏览器使用缓存里的资源,否则返回状态码200,服务器返回更新后的资源。

(下图为浏览器向服务器请求资源时,服务器返回的响应response的头部信息)

 

3.3.2  Etag

Etag数字签名配合If-Match(或If-None-Match)使用:一般的数字签名可以对资源的内容进行hash计算,浏览器第一次发送请求时,在浏览器第一次请求资源时,在服务器的响应头部信息中设置Etag,值为hash值,当浏览器再次对相同的资源发起请求时,浏览器会设置请求(request)的头部信息,设置 If-Match(或If-None-Match)为之前接收到的 Etag的值,这样服务器每次收到请求中的 If-Match(或If-None-Match)都会 重新计算资源内容的hash值,再对比,如果相同,则返回304,浏览器使用缓存,如果不相同,就返回更新后的内容。

(可以看出 Last-Modified 和 Etag 的工作原理都是一样的,只是 Last-Modified 记录的是修改的时间,而Etag以hash值的形式记录资源的内容)

3.3.3 Last-Modified 和 Etag的区别

  1. 某些服务器不能精确得到资源最后的修改时间,这样就无法通过 最后修改时间 来判断资源是否更新。
  2. Last-Modified 只能精确到秒。
  3. 一些资源虽然最后的修改时间变了,但是资源内容是没有变的,使用Last-Modified 的话,就会误以为资源改变了。
  4. Etag 的精度比Last-Modified高,要求资源字节级别一样,优先级高。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值