http 缓存机制(200 还是 304)

RFC文档

rfc2616 Hypertext Transfer Protocol – HTTP/1.1(已废弃)

rfc7234 Hypertext Transfer Protocol (HTTP/1.1): Caching

缓存状态码

200 OK (from cache)  是浏览器没有跟服务器确认,直接用了浏览器缓存;

304 Not Modified 是浏览器和服务器多确认了一次缓存有效性,再用的缓存。

304 Not Modified 比 200 OK (from cache) 慢,指的是浏览器还向服务器确认了下 “If-Not-Modified”,才用的缓存

缓存HTTP头信息

Date:原服务器发送该资源响应报文的时间(GMT格式)

Age:Age表示这个响应已经存活了多久了(HTTP/1.0的响应不带Age)

Expires:即在 HTTP 头中指明具体失效的时间(HTTP/1.0),Expires = HTTP-date

Pragma:no-cache,每次请求页面时都不要读缓存,兼容HTTP/1.0,优先级高于Expires(HTTP/1.0 + HTTP/1.1)

Cache Control:优先级高于Pragma、Expires(HTTP/1.1)

本地缓存,是指在客户端本地机器中的缓存。

共享缓存,处于客户端和服务器之间的缓存,例如:CDN。

请求 Cache Control

max-age可以接收缓存最长时间
max-stale可以接收过期的资源,但是过期时间必须小于 max-stale 值
min-fresh可以接收一个更新过的资源,fresh生命期大于其当前 Age 跟 min-fresh 值之和
no-cache在源服务器返回成功的验证之前不能使用缓存响应
no-store直接禁止浏览器和所有中继缓存存储返回的任何版本的响应
no-transform获取没有被转换过(比如压缩)的资源
only-if-cached希望获取缓存内容而不发起请求

响应 Cache Control

no-cache缓存必须重新校验
no-store不存储缓存
no-transform缓存内容时不能对改变任何数据
public响应可被任何缓存区缓存
private只在本地缓存,不允许任何中继缓存对其进行缓存
(例如,浏览器可以缓存,但是CDN不能缓存)
must-revalidate如果缓存的内容失效,请求必须发送到服务器以进行重新验证
(请求失败返回504,而非中间缓存CDN)
proxy-revalidate与must-revalidate类似,仅能用于共享缓存(如:CDN)
max-age只接受 Age 值小于 max-age 值,并且没有过期的资源
s-maxage仅能用于共享缓存,一般用在cache服务器上(如:CDN)

Cache Control Extensions

通过使用1个或多个cache-extension tokens扩展(可选)字段,服务器不识别则忽略掉

 
 
  1. Cache-Control: private, community="UCI"

Cache-Control 允许自由组合可选值

 
 
  1. Cache-Control: max-age=3600, must-revalidate

Last-Modified/If-Modified-Since:文件最后一次修改的时间(精度是秒,HTTP/1.0),需要Cache-Contral过期

Etag:当前资源在服务器的唯一标识(生成规则由服务器决定)ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的,优先级高于Last-Modified;在分布式的Web系统中,当访问落在不同的物理机上时会返回不同的ETag,进而导致304失效,降级为200请求(HTTP/1.1),需要Cache-Contral过期

如果 Last-Modified 和 ETag 同时被使用,则要求它们的验证都必须通过才会返回304,否则返回200。

Meta标签

meta是用来在HTML文档中模拟HTTP协议的响应头报文。在HTML页面加上meta标签来给请求报头加上请求字段。

 
 
  1. <meta http-equiv="Expires" content="0">
  2. <meta http-equiv="Pragma" content="no-cache">
  3. <meta http-equiv="Cache-Control" content="no-cache">

Pragma的meta标签只有IE能识别

“Pragma:No-cache”标记可能无法防止页面被缓存

优先级:Cache-Control > Pragma > Expires

清除浏览器中的缓存,必须从服务端获取最新内容,但不是所有浏览器都支持

缓存机制

Freshness

和浏览器策略以及Cache Control(HTTP/1.1)与Expires(HTTP/1.0)有关

最好的请求是不必与服务器进行通信的请求:通过响应的本地缓存,可以避免所有的网络延迟以及数据传输的数据成本。

服务器给响应设置显示过期时间(explicit expiration time),当请求资源时,只需要检测资源的过期状态,判断是否使用缓存。

服务器不提供一个显示过期时间,HTTP缓存通常会设置一个启发式过期时间(heuristic expiration time),采用算法通过其他值(例如Last-Modified)估计一个合理的时间。

如何判断响应是否新的?

 
 
  1. response_is_fresh = (freshness_lifetime > current_age)

freshness_lifetime计算,同时存在多个,按优先级获取

  • 如果是共享缓存,使用s-maxage

  • 如果有max-age字段,使用max-age

  • 如果有Expires字段,使用Expires超过Date的时间数

  • 如果没有显示过期时间设置,使用浏览器的启发式过期时间(heuristic expiration time)

current_age计算

  • age_value Age字段的值

  • date_value Date字段的值

  • now 当前时间

  • request_time 请求时间

  • response_time 响应时间

 
 
  1. apparent_age = max(0, response_time - date_value);
  2. response_delay = response_time - request_time;
  3. corrected_age_value = age_value + response_delay;
  4. corrected_initial_age = max(apparent_age, corrected_age_value);
  5. resident_time = now - response_time;
  6. current_age = corrected_initial_age + resident_time;

缓存策略

《http 缓存机制(200 还是 304)》

HTML5 Boilerplate 项目nginx配置文件样例

 
 
  1. # cache.appcache, your document html and data
  2. location ~* \.(?:manifest|appcache|html?|xml|json)$ {
  3. expires -1;
  4. }
  5. # Feed
  6. location ~* \.(?:rss|atom)$ {
  7. expires 1h;
  8. }
  9. # Media: images, icons, video, audio, HTC
  10. location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
  11. expires 1M;
  12. access_log off;
  13. add_header Cache-Control "public";
  14. }
  15. # CSS and Javascript
  16. location ~* \.(?:css|js)$ {
  17. expires 1y;
  18. access_log off;
  19. }

Validation

检查一个缓存的响应是否仍然可用

Last-Modified和ETag(entity-tag)

通过验证令牌可以进行高效的资源更新检查:如果资源未更改,则不会传输任何数据

《http 缓存机制(200 还是 304)》

 
 
  1. Status Code:304 Not Modified
  2. Response Head
  3. ETag:"578ba64c-7ddf"
  4. Last-Modified:Sun, 17 Jul 2016 15:37:48 GMT
  5. Request Head
  6. If-Modified-Since:Sun, 17 Jul 2016 15:37:48 GMT
  7. If-None-Match:"578ba64c-7ddf"

《http 缓存机制(200 还是 304)》

Invalidation

类似PUT、POST 和 DELETE的”非安全”请求可能会改变原服务端状态,在此期间缓存会让它们的内容过期失效。

当一个非安全的请求收到非错误的返回状态码(2xx或者3xx),缓存必须使请求URI的包括其他相关URI(s)的Location和Content-Location响应头字段失效。

为了防止服务器攻击拒绝,一个基于Location或Content-Location头域里的URI的无效性处理必须只有在host部分和请求URI里的host部分相同时才被执行。

注:只读请求(GET/HEAD)认为是“安全”的,详细可查看safe.methods

200 or 304

在没有设置Cache-Contral的情况下,设置Last-Modified和ETag缓存,会出现时而200(from cache),时而304 出现的情况。

chrome 测试 刷新 和 输入URL回车 测试并不会影响200(from cache)和304 的出现。

可能的情况,是在服务器没有设置显示缓存时间的情况下,freshness_lifetime是浏览器按某种算法计算出来,这个时间并不长,所以会出现这种情况。

设置Cache-Contral max-age的情况下,max-age过期后首次刷新会出现304(如果有更新内容,则是200),之后在max-age缓存过期之前刷新都是200(from cache)。

缓存方案

较长的过期时间,节省带宽,提高性能;更改资源的网址,强制用户下载新响应

《http 缓存机制(200 还是 304)》

按需更新,精确的缓存控制

静态资源CDN部署

更资源发布路径实现非覆盖式发布(多版本共存)

更多资料

本文对你有帮助?欢迎扫码加入前端学习小组微信群:

《http 缓存机制(200 还是 304)》

    原文作者:HTTP
    原文地址: https://juejin.im/entry/58ba3302570c350062124f68
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞