目录

一、HTTP缓存机制

二、HTTP缓存的类型

1、强缓存(本地缓存)——不与服务器通信

Expire——使用客户端绝对时间

Cache-Control——使用客户端与服务器相对时间

2、协商缓存——与服务器通信

Last-Modify/If-Modify-Since——最后修改时间

ETag/If-None-Match——唯一标识符

ETag扩展说明

既生Last-Modified何生Etag?

三、HTTP缓存机制执行流程

四、改进缓存方案

1、MD5/hash缓存

2、CDN缓存

CDN怎么缓存?


一、HTTP缓存机制

Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。

浏览器缓存也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。

在具体了解 HTTP 缓存之前先来明确几个术语:

  • 缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
  • 过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
  • 验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
  • 失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。

浏览器缓存主要是 HTTP 协议定义的缓存机制。HTML meta 标签,例如

<META HTTP-EQUIV="Pragma" CONTENT="no-store">

含义是让浏览器不缓存当前页面。但是代理服务器不解析 HTML 内容,一般应用广泛的是用 HTTP 头信息控制缓存。

Http缓存主要涉及三个角色:一是浏览器,二是浏览器的缓存数据库,三是服务器。三者之间的图示关系如下:

二、HTTP缓存的类型

Http缓存主要分为两种:强缓存和协商缓存。两种缓存分别通过Http报文头部不同的字段进行控制,下面将分别介绍两种缓存。

1、强缓存(本地缓存)——不与服务器通信

命中强缓存时,浏览器并不会将请求发送给服务器。在Chrome的开发者工具中看到http的返回码是200,但是在Size列会显示为(from *** cache)。

强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。

Expire——使用客户端绝对时间

Expire其指定了一个日期/时间, 在这个日期/时间之后,HTTP响应被认为是过时的。

该字段会返回一个时间,比如Expires:Thu, 27 Feb 2020 13:41:02 GMT。这个时间代表着这个资源的失效时间,也就是说在这个时间之前都是有效的,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当客户端本地时间被修改以后,服务器与客户端时间偏差变大以后,就会导致缓存混乱。于是发展出了Cache-Control。

相比Expire,cache-control的优先级更高,所以如果请求中还有一个置了 “max-age” 或者 “s-max-age” 指令的Cache-Control响应头,那么 Expires 头就会被忽略

Cache-Control——使用客户端与服务器相对时间

Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。

Cache-Control与Expires可以在服务端配置同时启用或者启用任意一个,同时启用的时候Cache-Control优先级高

Cache-Control 可以由多个字段组合而成,主要有以下几个取值:

max-age:

指定一个时间长度,在这个时间段内缓存是有效的,单位是s。例如设置 Cache-Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 * 60)天,第一次访问这个资源的时候,服务器端也返回了 Expires 字段,并且过期时间是一年后。

在没有禁用缓存并且没有超过有效时间的情况下,再次访问这个资源就命中了缓存,不会向服务器请求资源而是直接从浏览器缓存中取。

s-maxage:同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。

public:表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。

private:表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。

no-cache:强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器。不是字面意思上的不缓存。

no-store:禁止缓存,每次请求都要向服务器重新获取数据。

must-revalidate:指定如果页面是过期的,则去服务器进行获取。缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。这个指令并不常用,就不做过多的讨论了。

2、协商缓存——与服务器通信

协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问。

服务器根据http头信息中的Last-Modify/If-Modify-SinceEtag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。

Last-Modify/If-Modify-Since——最后修改时间

浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。

当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。

如果命中缓存,则返回http304,并且不会返回资源内容,并且不会返回Last-Modify。由于对比的服务端时间,所以客户端与服务端时间差距不会导致问题。但是有时候通过最后修改时间来判断资源是否修改还是不太准确(资源变化了最后修改时间也可以一致)。于是出现了ETag/If-None-Match。

ETag/If-None-Match——唯一标识符

与Last-Modify/If-Modify-Since不同的是,Etag/If-None-Match返回的是一个校验码(ETag: entity tag)。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。ETag值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。

ETag扩展说明

我们对ETag寄予厚望,希望它对于每一个url生成唯一的值,资源变化时ETag也发生变化。神秘的Etag是如何生成的呢?以Apache为例,ETag生成靠以下几种因子

  • 文件的i-node编号,此i-node非彼iNode。是Linux/Unix用来识别文件的编号。是的,识别文件用的不是文件名。使用命令’ls –I’可以看到。
  • 文件最后修改时间
  • 文件大小,生成Etag的时候,可以使用其中一种或几种因子,使用抗碰撞散列函数来生成。所以,理论上ETag也是会重复的,只是概率小到可以忽略。

既生Last-Modified何生Etag?

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间

2. 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存

3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

参考博客:https://www.cnblogs.com/ranyonsue/p/8918908.html

三、HTTP缓存机制执行流程

在浏览器第一次发起请求时,本地无缓存,向web服务器发送请求,服务器起端响应请求,浏览器端缓存。过程如下:

在第一次请求时,服务器会将页面最后修改时间通过Last-Modified标识由服务器发送给客户端,客户端记录修改时间;服务器还会生成一个Etag,并发送给客户端。

浏览器后续再次进行请求时:

浏览器缓存主要分为强强缓存(也称本地缓存)和协商缓存(也称弱缓存)。根据上图,浏览器在第一次请求发生后,再次发送请求过程:

(1)浏览器请求某一资源时,会先获取该资源缓存的header信息,然后根据header中的Cache-ControlExpires判断是否过期。

(2)若没过期则直接从缓存中获取资源信息,包括缓存的header的信息,所以此次请求不会与服务器进行通信。这里判断是否过期,则是强缓存相关。后面会讲Cache-ControlExpires相关。

如果显示已过期,浏览器会向服务器端发送请求,这个请求会携带第一次请求返回的有关缓存的header字段信息,比如客户端会通过If-None-Match将先前服务器端发送过来的Etag发送给服务器,服务会对比这个客户端发过来的Etag是否与服务器的相同。

(3)若相同,就将If-None-Match的值设为false,返回状态304,客户端继续使用本地缓存,不解析服务器端发回来的数据。

若不相同就将If-None-Match的值设为true,返回状态为200,客户端重新机械服务器端返回的数据。

(4)客户端还会通过If-Modified-Since头将先前服务器端发过来的最后修改时间戳发送给服务器,服务器端通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回最新的内容,如果是最新的,则返回304,客户端继续使用本地缓存。

四、改进缓存方案

1、MD5/hash缓存

通过不缓存html,为静态文件添加MD5或hash标识,解决浏览器无法跳过缓存过期时间主动感知文件变化问题。

2、CDN缓存

CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞、提高用户访问响应速度和命中率。

http缓存是浏览器端缓存,cdn是服务器端缓存。

CDN怎么缓存?

和Http类似,客户端请求数据时,先从本地缓存查找,如果被请求数据没有过期,拿过来用,如果过期,就向CDN边缘节点发起请求。CDN便会检测被请求的数据是否过期,如果没有过期,就返回数据给客户端,如果过期,CDN再向源站发送请求获取新数据。和买家买货,卖家没货,卖家再进货一个道理。

HTTP协议缓存机制相关推荐

  1. http协议+缓存机制

    http协议+缓存机制 文章目录 http协议+缓存机制 前言 一.http 1.http1.0/1.1 2.http2.0 3.一个TCP连接可以发送多少个HTTP请求 4.浏览器最多可以向同一个h ...

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

    浏览器缓存机制 浏览器缓存机制主要是 HTTP 协议定义的缓存机制. HTTP 协议中有关缓存的缓存信息头的关键字有 Cache-Control,Pragma,Expires,Last-Modifie ...

  3. 互联网协议 — DNS 缓存机制

    目录 文章目录 目录 DNS 缓存机制 基于缓存的 DNS 域名解析流程 DNS 缓存使用面临的问题 互联网环境缓存应用面临的问题 企业内网缓存应用面临的问题 DNS 缓存在实际应用中的考虑 主动操作 ...

  4. 802.11协议精读9:初探节能模式(PS mode)与缓存机制

    https://zhuanlan.zhihu.com/p/21505178 序言 由于802.11的协议工作机制,如果其一直处于工作状态下,那么能耗还是比较大的,尤其移动设备的电量有限,所以在802. ...

  5. Spring mvc HTTP协议之缓存机制

    概述 Spring MVC 支持HTTP协议的 Last-Modified 缓存机制. 1. 在客户端地一次输入URL时,服务器端会返回内容和状态码200, 表示请求成功,同时会添加一个"L ...

  6. 缓存服务器协议有哪些,HTTP 协议的缓存机制概述

    HTTP 协议的缓存机制涉及到多个请求头字段,而且整个缓存机制的细节行为也存在各种情况的差异,譬如说什么时候访问本地缓存不发送请求,什么时候发送请求查看资源是否更新,获取 response 什么情况下 ...

  7. 网络协议(12) 彻底弄懂HTTP缓存机制及原理

    前言 Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是必备的知识技能. 但是对于很多前端 ...

  8. 清除浏览器缓存之后为什么还是显示旧的html页面_H5缓存机制浅析-移动端Web加载性能优化...

    1 H5缓存机制介绍 H5,即HTML5,是新一代的HTML标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5引入的离线存储,这意味着 web 应用可进行缓存,并可在没 ...

  9. max点缓存烘焙帧_深入理解浏览器的缓存机制

    一.前言 缓存可以说是性能优化中简单高效的一种优化方式了.一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷. 对于一个数据请求来说,可 ...

最新文章

  1. 对于一些手机内存概念的思考、深入理解java的finalize,对于内存优化的小总结...
  2. 海思 HI35* rtsp服务器
  3. 汇编指令中的字母会区分大小写吗?(除了字符型数据,其他地方都不区分)
  4. 大数据与智能算法(二-应用级技术)-SMU在线学习笔记
  5. 解决 Gradle 进行多模块开发时,模块相互依赖的问题
  6. libjpeg-turbo(2)
  7. Kudu : kudu 主键相关
  8. 沙盒机制和应用程序目录
  9. python可打印字符_测试一个python字符串是否可打印
  10. ubuntu 17.10 如何设置合盖不关机
  11. 思科CCNP在OSPF中设置LSA的简单命令汇总
  12. Microsoft Store打不开解决办法
  13. word2016用尾注引用参考文献
  14. 化工设计常用的三维软件有哪些?SmartPlant 3D、PDMS、SolidWorks......
  15. Google Chrome源码剖析
  16. vue后台管理upload(图片上传)
  17. 电子学会 全国青少年软件编程等级考试(三级--八级)
  18. 武汉大学计算机学院国家重点实验室,实验室简介
  19. LR_中央控制器、负载生成器
  20. python +selenium 爬取淘宝网商品信息

热门文章

  1. Toad for DB2中 双竖线||的作用是什么
  2. 如何降低ue4 cpu消耗_如何有效降低CPU温度,六个步骤教你如何使用液金导热!...
  3. python input 默认值_在python中为dictionary创建默认值
  4. linux pgrep命令使用示例
  5. java向word中插入Excel附件
  6. UI设计自学困难吗?
  7. 答题活动小程序复盘记录
  8. Java学习笔记——多态(实例详解)
  9. 【3DsMAX】从零开始建房(1)
  10. pathon----爬虫学习1