HTTP缓存

Http缓存

  • 缓存控制:控制缓存的开关,用于标识请求或访问中是否开启了缓存,使用了哪种缓存方式。

  • 缓存校验:如果缓存控制开关打开,如何校验缓存,比如怎么定义缓存的有效期,怎么确保缓存是最新的。

缓存控制

1. Expires

2. Cache-Control

3. Pragma

Expires

Expires 响应头包含日期/时间, 即在此时候之后,响应过期。

Expires因为是对时间设定的,且时间是Greenwich Mean Time (GMT),而不是本地时间,所以对时间要求较高。

Response Header
Expires: Wed, 21 Oct 2020 17:28:00 GMT

Cache-control

Cache-Control 通用消息头字段,被用于在http请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求中设置的指令,不一定被包含在响应中。

指令不区分大小写,并且具有可选参数,可以用令牌或者带引号的字符串语法。多个指令以逗号分隔。

缓存请求指令

客户端可以在HTTP请求中使用的标准 Cache-Control 指令。

Request Header
Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: no-transform
Cache-Control: only-if-cached

缓存响应指令

服务器可以在响应中使用的标准 Cache-Control 指令。

Response Header
Cache-Control: must-revalidate
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: no-transform
Cache-Control: public
Cache-Control: private
Cache-Control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-Control: s-maxage=<seconds>

Cache-control的值可以按以下性质分类

1.可缓存性、控制开关

  • 否可以缓存,以及是私有还是共享缓存
public

表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存,即使是通常不可缓存的内容。(例如:1.该响应没有max-age指令或Expires消息头;2. 该响应对应的请求方法是 POST 。)

private

表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容,比如:对应用户的本地浏览器。

no-cache

在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。

no-store

缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。

2. 缓存到期

max-age=

设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。

s-maxage=

覆盖max-age或者Expires头,但是仅适用于共享缓存(比如各个代理),私有缓存会忽略它。

max-stale[=]

表明客户端愿意接收一个已经过期的资源。可以设置一个可选的秒数,表示响应不能已经过时超过该给定的时间。

min-fresh=

表示客户端希望获取一个能在指定的秒数内保持其最新状态的响应。

3.重新验证和重新加载

must-revalidate

一旦资源过期(比如已经超过max-age),在成功向原始服务器验证之前,缓存不能用该资源响应后续请求。

proxy-revalidate

与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。

4.其他

no-transform

不得对资源进行转换或转变。Content-Encoding、Content-Range、Content-Type等HTTP头不能由代理修改。例如,非透明代理或者如Google’s Light Mode可能对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。no-transform指令不允许这样做。

only-if-cached

表明客户端只接受已缓存的响应,并且不要向原始服务器检查是否有更新的拷贝。

Cache-Control缓存策略

HTTP/1.1定义的 Cache-Control 头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。

1.没有缓存

缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。

Request Header
Cache-Control: no-store

表示客户端不希望这个请求的响应进行任何缓存

Response Header
Cache-Control: no-store

表示服务端不希望对个资源进行任何缓存

2.缓存但重新验证

如下头部定义,此方式下,每次有请求发出时,缓存会将此请求发到服务器,服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。

Request Header
Cache-Control: no-cache

表示客户端希望用协商缓存的方式进行缓存

Response Header
Cache-Control: no-cache

表示服务端希望用协商缓存的方式进行缓存

3.私有和公共缓存

“public” 指令表示该响应可以被任何中间人(比如中间代理、CDN等)缓存。若指定了"public",则一些通常不被中间人缓存的页面(因为默认是private)(比如 带有HTTP验证信息(帐号密码)的页面 或 某些特定状态码的页面),将会被其缓存。

“private” 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。

Response Header
Cache-Control: private
or
Cache-Control: public

可以结合协商缓存

Cache-Control: public,no-cache
Cache-Control: private,no-cache

4.强缓存

过期机制中,最重要的指令是 “max-age=”,表示资源能够被缓存(保持新鲜)的最大时间。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。

Request Header
Cache-Control: max-age=31536000

配合Age请求头 来表示客户端缓存资源是否到期

Cache-Control: max-age=31536000
Age: 10
Response Header
Cache-Control: max-age=31536000

可以结合私有和公共缓存

私有强缓存

Cache-Control: private,max-age=31536000

公共强缓存

Cache-Control: public,max-age=31536000

表示服务端当前资源如果做缓存后可用的时间
5.验证方式

当使用了 “must-revalidate” 指令,那就意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。

Response Header
Cache-Control: must-revalidate

表示服务端希望客户端进行验证

Cache-control --VS-- Expires

Cache-control内容要远比Expires复杂的多,也是本文重点。

  1. ExpiresHTTP1.0协议中用来控制缓存的http头,Cache-ControlHTTP1.1协议新版的API。现在首选 Cache-Control。如果在Cache-Control响应头设置了 “max-age” 或者 “s-max-age” 指令,那么 Expires 响应头会被忽略。

  2. HTTP1.1协议中的,因为有了Cache-control,所以可以忽略上面提到的Expires。因为Cache-Control相对于Expires更加具体,细致。
    且,就算同时设置了Cache-ControlExpiresCache-Control的优先级也高于Expires

Pragma

Pragma 是一个在 HTTP/1.0 中规定的通用首部,这个首部的效果依赖于不同的实现,所以在“请求-响应”链中可能会有不同的效果。它用来向后兼容只支持 HTTP/1.0 协议的缓存服务器,那时候 HTTP/1.1 协议中的 Cache-Control 还没有出来。

Cache-Control: no-cache
Pragma: no-cache 

**注意:**由于 Pragma 在 HTTP 响应中的行为没有确切规范,所以不能可靠替代 HTTP/1.1 中通用首部 Cache-Control,尽管在请求中,假如 Cache-Control 不存在的话,它的行为与 Cache-Control: no-cache 一致。建议只在需要兼容 HTTP/1.0 客户端的场合下应用 Pragma 首部。

缓存的两种形式

  • 强缓存:浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息),若命中直接从缓存中获取资源信息,包括缓存header信息;本次请求根本就不会与服务器进行通讯

  • 协商缓存:若是没有命中强缓存,浏览器会发送请求到服务器,请求会携带第一次请求返回的有关缓存的header字段信息(Last-Modified/If-Modified-Since和Etag/If-None-Match),由服务器根据请求中的相关header信息来比对结果是否协商缓存命中;若命中,则服务器返回新的响应header信息更新缓存中的对应header信息,可是并不返回资源内容,它会告知浏览器能够直接从缓存获取;不然返回最新的资源内容

缓存校验

当缓存控制采用

Cache-Control: no-cache
Cache-Control: max-age=0
Cache-Control: must-revalidate

以上等情况时表示,表示使用协商缓存的方式
响应头ETag —对应— 请求头If-None-Match

响应头Last-Modified —对应— 请求头If-Modified-Since

ETag

作为缓存的一种强校验器,ETag 响应头是一个对用户代理(User Agent, 下面简称UA)不透明的值。对于像浏览器这样的HTTP UA,不知道ETag代表什么,不能预测它的值是多少。如果资源请求的响应头里含有ETag, 客户端可以在后续的请求的头中带上 If-None-Match 头来验证缓存。

Reqsponse Header
ETag: "3e86-410-3596fbbc"

If-None-Match

If-None-Match 是一个条件式请求首部。对于 GET 和 HEAD 请求方法来说,当且仅当服务器上没有任何资源的ETag属性值与这个首部中列出的相匹配的时候,服务器端会才返回所请求的资源,响应码为200。对于其他方法来说,当且仅当最终确认没有已存在的资源的ETag属性值与这个首部中所列出的相匹配的时候,才会对请求进行相应的处理。

Request Header
If-None-Match: "3e86-410-3596fbbc"

一般ETag的值是资源的MD5值,由服务端开发人员在响应头中返回,当客户端再次发起相同的请求时,请求头中添加If-None-Match

If-None-Match: "3e86-410-3596fbbc"

服务端人员可以通过下面的伪代码来判断如何进行返回

if(request.header("If-None-Match") == "3e86-410-3596fbbc") 
{
    response.statuscode = 304;
}
else
{
    response.write(string);
}

If-None-Match:告诉服务器如果一致,返回状态码304,不一致则返回资源。

Last-Modified

Last-Modified响应头可以作为一种弱校验器。说它弱是因为它只能精确到一秒。如果响应头里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since 来验证缓存。

Reponse Header

Last-Modified 文件最后修改时间 秒级别

Last-Modified: Thu, 03 Jul 2018 00:00:00 GMT

If-Modified-Since

If-Modified-Since 是一个条件式请求首部,服务器只在所请求的资源在给定的日期时间之后对内容进行过修改的情况下才会将资源返回,状态码为 200 。如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的 304 响应,而在 Last-Modified 首部中会带有上次修改时间。 不同于 If-Unmodified-Since, If-Modified-Since 只可以用在 GET 或 HEAD 请求中。

当与 If-None-Match 一同出现时,它(If-Modified-Since)会被忽略掉,除非服务器不支持 If-None-Match。

Request Header
If-Modified-Since: Thu, 03 Jul 2018 00:00:00 GMT

如果时间一致,那么返回HTTP状态码304(不返回文件内容),客户端接到之后,就直接把本地缓存文件显示到浏览器中。

如果时间不一致,就返回HTTP状态码200和新的文件内容,客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示到浏览器中。

从这个GMT指定时间开始 未修改过

请求网站的时间

Date: Tue, 11 Jul 2000 18:23:51GMT

参考文献

HTTP Headers

HTTP 缓存

http协商缓存VS强缓存

HTTP缓存讲义

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值