原创文章首发于公众号:「码农富哥」,欢迎收藏和关注,如转载请注明出处!

什么是HTTP缓存

HTTP 缓存可以说是HTTP性能优化中简单高效的一种优化方式了,缓存是一种保存资源副本并在下次请求时直接使用该副本的技术,当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。

一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,节省网络流量,并且由于缓存文件可以重复利用,降低网络负荷,提高客户端响应。

所以,学会利用HTTP缓存是很有必要的

在此,我会向大家系统的介绍HTTP缓存机制,期望对各位正确的理解HTTP缓存有所帮助。

缓存策略

在阐述HTTP不同缓存策略之前,我们需要知道用户刷新/访问行为 的手段分成三类:

  • 在URI输入栏中输入然后回车/通过书签访问
  • F5/点击工具栏中的刷新按钮/右键菜单重新加载
  • Ctl+F5 (完全不使用HTTP缓存)

不同的刷新手段,会导致浏览器使用不同的缓存策略,我们下面会分析到

HTTP 缓存主要是通过请求和响应报文头中的对应 Header 信息,来控制缓存的策略。

响应头中相关字段为Expires、Cache-Control、Last-Modified、Etag。

HTTP缓存的类型很多,根据是否需要重新向服务器发起请求来分类包括两种:强制缓存 和 对比缓存

假设浏览器有一个缓存数据库用于本地缓存,先看看浏览器请求资源的情况:



强制缓存:

在浏览器已经缓存数据的情况下,使用强制缓存去请求数据的流程是这样的:

强制缓存



从流程图可以看到,强制缓存,在缓存数据未失效的情况下,可以直接使用缓存数据,不需要再请求服务器,那么浏览器是如何判断缓存数据是否失效呢?

对于强制缓存来说,响应header中会有两个字段来标明失效规则(Expires/Cache-Control):

  • Expires:

    Expires是HTTP1.0的产物了,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。但是很多网站还是对它做了兼容。它的值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。

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

    在HTTP 1.1 的版本,Expires被Cache-Control替代。
  • Cache-Control:

    Cache-Control是最重要的规则。常见的取值有private、public、no-cache、max-age,no-store,默认为private。

    (1) max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;

    (2) s-maxage:和max-age是一样的,不过它只针对代理服务器缓存而言;

    (3)public:指示响应可被任何缓存区缓存;

    (4)private:只能针对个人用户,而不能被代理服务器缓存;

    (5)no-cache:强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到 请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。这个很容易让人产生误解,使人误 以为是响应不被缓存。实际上Cache-Control: no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。

    (6)no-store:禁止一切缓存(这个才是响应不被缓存的意思)。

举个例子:

比如一个资源响应头是:

cache-control: public, max-age=31536000

那么这个资源会被缓存31536000秒(365天),在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。

那么我们试试再次访问资源,会有以下的响应:

可以看到HTTP状态码是200,Size这个字段显示:disk cache,说明HTTP响应报文大小是0,浏览器确实走了强制缓存,没有再跟浏览器交互。

我们上面说了,不同的访问/刷新手段,会使浏览器使用不同的缓存策略,要让浏览器走强制缓存对请求方式有一个要求: 在URI输入栏中输入然后回车/通过书签访问

对比缓存:

在浏览器已经缓存数据的情况下,使用对比缓存去请求数据的流程是这样的:

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

这个问题,我们现在来探讨一下。

对比缓存,顾名思义,需要进行比较判断是否可以使用缓存。

浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给浏览器,浏览器将二者备份至缓存数据库中。

当浏览器再次请求数据时,浏览器将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。

举个例子:

第一次访问:

第二次访问:

对比缓存,响应header中会有两个字段来标明规则

  • Last-Modified / If-Modified-Since

    服务器响应请求时,会通过Last-ModifiedHTTP头告诉浏览器资源的最后修改时间,浏览器本地对资源缓存起来,之后再请求的时候,会带上一个HTTP头If-Modified-Since,这个值就是服务器上一次给的Last-Modified的时间,服务器会拿着浏览器传过来的时间比对资源当前最后的修改时间,如果大于If-Modified-Since,则说明资源修改过了,浏览器不能再使用缓存,服务器重新一份完整的资源浏览器,否则浏览器可以继续使用缓存,并返回304状态码

  • Etag / If-None-Match(优先级高于Last-Modified / If-Modified-Since)

    服务器响应请求时,通过EtagHTTP头部告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定),浏览器再次请求时,就会带上一个头If-None-Match,这个值就是服务器上一次给的Etag的值,服务器比对一下资源当前的Etag是否跟If-None-Match一致,不一致则说明资源修改过了,浏览器不能再使用缓存,否则浏览器可以继续使用缓存,并返回304状态码

值得注意的是:Etag 的校验优先级高于 Last-Modified

看个例子:

第一次请求,服务器的响应头包含了

第二次请求,浏览器的请求头

总结

我们再看一下HTTP缓存的一个总概流程图:

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

最后

文章如果对你有收获,可以收藏转发,这也是对我写作的肯定!另外可以关注我公众号「码农富哥」 (搜索id:coder2025),我会持续输出Python,服务端架构,计算机基础(MySQL, Linux,TCP/IP)的 原创 文章

5分钟看懂系列:HTTP缓存机制详解的更多相关文章

  1. RF射频传输,原理介绍,三分钟看懂!发射功率、接收灵敏度详解!

    射频是什么? 官方说法:RF,Radio Frequency. (不懂的人,看了还是不懂,不过对于物联网行业的开发工程师.产品经理和项目经理,还是有需要对射频有个基础了解的.) 燚智能解读: 两个人, ...

  2. 浏览器 HTTP 协议缓存机制详解

    最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control.为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag, ...

  3. nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解

    1.缓存的分类 缓存分为服务端侧(server side,比如 Nginx.Apache)和客户端侧(client side,比如 web browser). 服务端缓存又分为 代理服务器缓存 和 反 ...

  4. PHP缓存机制详解

    一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...

  5. 二,PHP缓存机制详解

    一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...

  6. hibernate缓存机制详解

    hiberante面试题—hibernate缓存机制详解   这是面试中经常问到的一个问题,可以按照我的思路回答,准你回答得很完美.首先说下Hibernate缓存的作用(即为什么要用缓存机制),然后再 ...

  7. 浏览器 HTTP 协议缓存机制详解--网络缓存决策机制流程图

    1.缓存的分类 2.浏览器缓存机制详解 2.1 HTML Meta标签控制缓存 2.2 HTTP头信息控制缓存 2.2.1 浏览器请求流程 2.2.2 几个重要概念解释 3.用户行为与缓存 4.Ref ...

  8. IOS缓存机制详解

    资料均来自互联网,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任. 人魔七七:http://www.cnblogs.com/qiqibo/ 为什么要有缓存 应用需要 ...

  9. 【转】IOS缓存机制详解

    人魔七七:http://www.cnblogs.com/qiqibo/ 为什么要有缓存 应用需要离线工作的主要原因就是改善应用所表现出的性能.将应用内容缓存起来就可以支持离线.我们可以用两种不同的缓存 ...

随机推荐

  1. 点分治 (等级排) codeforces 321C

    Now Fox Ciel becomes a commander of Tree Land. Tree Land, like its name said, has n cities connected ...

  2. 缓存读写策略 - Cache Aside.md

    场景描述 比如一条数据同时存在数据库.缓存,现在你要更新此数据,你会怎么更新? 先更新数据库?还是先更新缓存? 其实这两种方式都有问题. (1)先更新数据库,后更新缓存 这样会造成数据不一致. A 先 ...

  3. Redis Sentinel 高可用机制

    内容目录: Sentinel 如何工作的? 核心配置项 怎么选出新 master 的? Sentinel 有多个,具体谁来执行故障转移? Sentinel 是怎么发现 slave 和其他 sentin ...

  4. pandas时间序列常用操作

    目录 一.时间序列是什么 二.时间序列的选取 三.时间序列的生成 四.时间序列的偏移量 五.时间前移或后移 五.时区处理 六.时期及算术运算 七.频率转换 一.时间序列是什么 时间序列在多个时间点观察 ...

  5. MYGUI3.2改造——完善windows下的文字显示

    MYGUI 3.2 是支持中文显示的——往“MyGUI_Fonts.xml”文件里添加上中文的编码范围即可,这个网上有很多. 能显示中文后,再添加中文的自动换行,这个网上有:http://blog.s ...

  6. python的数据类型之列表list

    列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现.例如: stus = ["zhangsan","lisi","wangwu ...

  7. Docker底层架构之容器格式

    最初,Docker 采用了 LXC 中的容器格式.自 1.20 版本开始,Docker 也开始支持新的 libcontainer 格式,并作为默认选项.

  8. REST 风格架构

       ------------------------------ 时间不多了, 抓紧做一些有意义的事情 REST 风格架构   1. 他是面向资源进行开发的   2. 他是基于HTTP 协议进行开发 ...

  9. Spring注解开发系列VII --- Servlet3.0

    Servlet3.0简介 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用 ...

  10. SpringBoot分布式篇Ⅶ --- 整合Dubbo

    在分布式系统中, 国内常用zookeeper+dubbo组合,而Spring Boot推荐使用全栈的Spring,Spring Boot,Spring Cloud. 分布式系统: 一.Zookeepe ...