美文网首页Web前端之路
从需求看HTTP缓存

从需求看HTTP缓存

作者: 单调先生 | 来源:发表于2020-05-24 23:05 被阅读0次

前端经常会被问HTTP缓存,那么HTTP缓存的发展了解多少呢?为什么会出现各种不同的缓存字段?本篇文章会从缓存的类型开始,逐一说明缓存相关的HTTP字段,相信读完会对以上的问题有所了解。注意,以下讲解只针对HTTP缓存的情况。

缓存分强缓存协商缓存两种,简单来讲的话,强缓存期间请求不会到达服务器,即在缓存有效期内命中缓存,浏览器会使用本地缓存;协商缓存是在没有命中缓存或强缓存失效的情况下,与服务器进行协商来决定返回的请求资源。大概的流程如下:

简略的请求流程
看完上图,从整体上我们了解了HTTP请求的流程,那么这里又引出一些问题,如何知道强缓存的存在?依赖什么条件来确定本地是否有效呢?要解答这些问题,就得知道两个HTTP响应头字段ExpiresCache-Control
HTTP/1.0规范中,响应头字段有一个Expires字段,用于表示当前资源过期的时间。该字段描述的是一个绝对时间,由服务器返回,客户端本地只要超过这个时间则缓存失效。
示例Expires: Sun, 24 May 2020 07:41:19 GMT
Expires是最初的缓存控制字段,为它开始web应用减少了很多不必要的带宽浪费,可以指定一些不常更新的文件形成缓存。但开发者们很快发现了新的问题,Expires依赖客户端的时间进行判断,客户端修改了时间会影响缓存的有效性,这在某些情况下会比较致命,比如一个重要文件,理应在今天过期,但由于客户端时间修改成了去年,造成了缓存没有刷新,这就会很尴尬。为了解决这个问题,在HTTP/1.1中加入了Cache-Control字段来控制缓存,以满足更多的需求,配置如下。需要注意的是,该字段优先级高于Expires
  • public 可以被所有用户缓存,这里包括浏览器、代理服务器、CDN等。
  • private 只能被浏览器缓存,不允许被其它如代理服务器缓存。
  • no-store 不缓存
  • no-cache 先缓存本地,但命中缓存后必须与服务器验证资源新鲜度才能使用。这里注意,不要被名字误导成不缓存了。
  • max-age 用相对时间来表示缓存有效期,表示缓存将在XX秒后失效。示例Cache-Control: max-age=315360000
    Cache-Control设置

如果在缓存有效期内命中缓存,则使用强缓存,但是,如果命中缓存时缓存失效了怎么办?这个时候就要进入协商缓存流程了。进入协商缓存的条件不单是缓存失效,还包含以下三种情况:

  • 第一次请求服务器,返回的响应头中没有Cache-ControlExpires
  • Cache-Control:max-ageExpires导致的缓存失效
  • Cache-Control: no-cache

当存在以上三种情况时,第二次请求服务器就会进入协商缓存流程。协商缓存过程也涉及了HTTP状态码的改变,当请求发现服务器存在缓存或且缓存没有更新时,更新缓存时间并返回304 Not Modified;如果缓存失效,则服务器会把最新资源的完整版返回给浏览器,状态码为200 OK。看到这里大概就已经明白了协商缓存的过程,但细想一下还有一些没有说清楚的地方,服务器是如何校验缓存的新鲜度的呢?

Last-Modified/If-Modified-Since

当浏览器首次请求服务器资源时,服务器会将请求资源的最新修改时间Last-Modified: Tue, 07 Apr 2020 06:24:10 GMT通过响应头部返回给浏览器,浏览器在下次发起同一资源请求时会带上该信息,通过在请求头部设置If-Modified-Since: Tue, 07 Apr 2020 06:24:10 GMT,服务器会比对Last-Modified/If-Modified-Since如果服务器的资源有更新,则将最新的资源返回给浏览器,并更新响应头中的Last-Modified值,此时响应状态码为200 OK;如果服务器资源没有更新(两者时间一致),浏览器直接使用缓存即可,此时响应状态码为304 Not Modified

ETag/If-None-Match/If-Match

理论上通过比对资源的最新更新时间即可判断缓存是否有效,但实际操作中还是会遇到问题,比如资源文件在一秒内多次修改、资源经过编辑但没有发生实质内容修改的情况,这些问题表明以Last-Modified来判断还不够精确,我们需要引入ETag字段。大体流程上ETagLast-Modified的校验差不多,区别在于ETag不使用文件修改时间,而是使用文件内容摘要算出来的hash值进行判断,只要资源实质发生修改就会刷新hash值。服务器通过响应头中的ETag告知浏览器文件缓存信息,那么浏览器是如何把ETag的信息发送给服务器的呢?有以下两种形式:

  • If-None-Match: ETag value:通知服务器,如果没有匹配上,则需要重新发送资源;如果匹配上则直接返回304 Not Modified。一般浏览器使用该字段来回传ETag值。
  • If-Match: ETag value:通知服务器,如果没有匹配上ETag,或当前ETag: *但没有资源实体,则返回412 Precondition Failed;如果匹配上了,则服务器不做任何处理。

采用分布式服务器(如CDN)时,需要保证各服务器上的ETag算法一致,才不会出现A服务器与B服务器同一文件不同ETag值的出现。

Pragma

在整理资料的时候还发现了这个字段,该字段是HTTP/1.0的遗留之物,按辈分讲与Expires平齐。该字段用来定义是否需要缓存,可选值只有Pragma: no-cache,这个就可以按照字面意义理解成不进行缓存,即每次都会请求服务器的资源。优先级来讲Pragma > Cache-Control > Expires,当然,现代规范还是推荐使用Cache-Control的。

相关文章

  • 从需求看HTTP缓存

    前端经常会被问HTTP缓存,那么HTTP缓存的发展了解多少呢?为什么会出现各种不同的缓存字段?本篇文章会从缓存的类...

  • 浏览器强缓存和协商缓存

    HTTP强缓存和协商缓存 HTTP基于缓存策略三要素分解法 从性能优化的角度看缓存 https://github....

  • 从HTTP响应头看各家CDN缓存技术

    从HTTP响应头看各家CDN缓存技术 从HTTP响应头看各家CDN缓存技术 由于国内各家电信运营商互联互通的壁垒,...

  • HTTP缓存原理

    什么是HTTP缓存 HTTP缓存通常指浏览器缓存,基于HTTP中header字段实现HTTP缓存分为强缓存和协商缓...

  • 前端缓存

    前端缓存 前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务...

  • 从WebView缓存聊到Http 的缓存机制

    版权声明:本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有。未经允许,不得转载。 一、前...

  • 前端缓存详解

    一、前言 前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务...

  • HTTP缓存策略

    本篇是对承香墨影_图解 HTTP 的缓存机制 | 实用 HTTP的学习笔记 一、缓存的作用 为了更快地响应。从网络...

  • PWA笔记一:Web的万物基础缓存

    前言 这里讨论的缓存包括两种,一种是HTTP缓存,一种是Service Worker缓存。 HTTP缓存 HTTP...

  • 前端缓存的理解 或者 前端数据持久化的理解(强制缓存、协商缓存)

    前端缓存分为HTTP缓存和浏览器缓存 其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器代码上设置;而...

网友评论

    本文标题:从需求看HTTP缓存

    本文链接:https://www.haomeiwen.com/subject/obqjahtx.html