http 缓存,有时候静态资源没更新的情况下,不需要每次都去服务器获取,减少资源的请求。

Http 报文中与缓存相关的首部字段

1. 通用首部字段(就是请求报文和响应报文都能用上的字段)

2. 请求首部字段

3. 响应首部字段

4. 实体首部字段

废弃字段

  http 1.0 版本有 pragma 和 expires 字段。现在字段被抛弃了,但是为了向下兼容,还是有很多网站有带上这两个字段。

pragma 

  pragma 只有no-cache 一个属性值,和 Cache-Contorl 中的 no-cache 一致。

强缓存

  Expires:的值对应一个GMT(格林尼治时间),比如“Fri, 27 May 2022 12:02:01 GMT”来告诉浏览器资源缓存过期的绝对时间,如果还没过该时间点则不发请求。响应报文中Expires定义的缓存时间是相对服务器上的时间而言的,客户端上的时间跟服务器上的时间不一致(特别是用户修改了自己电脑的系统时间),那缓存时间可能就没啥意义了。

  Cache-Control: 是http/1.1中新增的属性,在请求头和响应头中都可以使用。其中 max-age 值为相对时间,例 Cache-Control:max-age=700, 是相对响应报文中的 Date 字段 700秒,这样就算客户端跟服务器的时间不一致,也没什么问题了。

  Date 字段是服务器发送该资源响应报文的时间(GMT格式),连续F5刷新发现 Date 的值都没变化,则说明你当前请求是命中了代理服务器的缓存。

  以下都是 Cache-Control 字段值

  可缓存性

  • public 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
  • private 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)
  • no-cache 不使用强缓存,需要与服务器验协商缓存验证。
  • no-store 缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。

  过期

  • max-age=<seconds> 缓存存储的最大周期,超过这个周期被认为过期。
  • s-maxage=<seconds> 设置共享缓存。会覆盖max-ageexpires,私有缓存会忽略它
  • max-stale[=<seconds>] 客户端愿意接收一个已经过期的资源,可以设置一个可选的秒数,表示响应不能已经过时超过该给定的时间。
  • min-fresh=<seconds> 客户端希望在指定的时间内获取最新的响应

  重新验证和重新加载

  • must-revalidate 如页面过期,则去服务器进行获取。
  • proxy-revalidatemust-revalidate 作用相同,但是用于共享缓存。

  其他

  • only-if-cached 不进行网络请求,完全只使用缓存。
  • no-transform 不得对资源进行转换和转变。例如,不得对图像格式进行转换。

  若报文中同时出现了 Pragma、Expires 和 Cache-Control, 优先级为 Expires < Pragma < Cache-Control 。

  Cache-Control 允许自由组合可选值   Cache-Control: max-age=3600, must-revalidate

  组合的方式也会有些限制,比如 no-cache 就不能和 max-age、min-fresh、max-stale 一起搭配使用。

  组合的形式还能做一些浏览器行为不一致的兼容处理。例如在IE我们可以使用 no-cache 来防止点击“后退”按钮时页面资源从缓存加载,但在 Firefox 中,需要使用 no-store 才能防止历史回退时浏览器不从缓存中去读取数据,故我们在响应报头加上如下组合值即可做兼容处理:Cache-Control: no-cache, no-store

协商缓存

   强缓会存在这样的问题:

    1、缓存时间到了,但是其实服务器资源并未更新,再次请求一次,如果文件大的话会浪费带宽和时间 

    2、缓存时间未到,服务器资源更新了,客户端未请求最新资源  

  所以Http1.1 新增以下几个字段

  Last-Modified / If-Modified-Since

  1. 在服务器在响应请求时,会通过 Last-Modified 告诉浏览器资源的最后修改时间。
  2. 浏览器再次请求服务器的时候,请求头会包含 if-Modified-Since 字段,后面跟着在服务器传过来的 Last-Modified 的最后修改时间。
  3. 服务端收到此请求头发现有 if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回 304 和响应报文头,浏览器只需要从缓存中获取信息即可。如果已经修改,那么开始传输响应一个整体,服务器返回:200 OK;

  Last-Modified 时间精度为1秒,如果1秒内更新,服务器资源更新了,导致资源不准确,或服务器资源更新了,但是资源的内容其实没改变,这时候就又发生了没必要的请求,所以出现了 ETag

  ETag / If-None-Match

    1、服务器会通过某种算法,给资源计算得出一个唯一标志符(比如md5标志,哈希值),资源内容变化都会导致 ETag 变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的。

    2、在浏览器发起请求,浏览器的请求报文头会包含 If-None-Match 字段,其值为上次返回的Etag发送给服务器,

    3、服务器接收到次报文后发现 If-None-Match 则与被请求资源的唯一标识进行对比。如果相同说明资源内容没有修改,则响应返 304,浏览器直接从缓存中获取数据信息。如果不同则说明资源被改动过,则响应整个资源内容,返回状态码 200。

    需要注意的是,如果资源是走分布式服务器(比如CDN)存储的情况,需要这些服务器上计算ETag唯一值的算法保持一致,才不会导致明明同一个文件,在服务器A和服务器B上生成的ETag却不一样。

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

如果 Expires 和 Cache-Control:max-age 都过期了,或 Cache-Contorl 为 no-cache,就会进入协商缓存;

大多数浏览器在点击刷新按钮或按F5时会自行加上“Cache-Control:max-age=0”请求字段,也就是跳过强缓存;

选中url地址栏并按回车键走强缓存(不会被强行加上Cache-Control);

ctrl+F5 这是跳过强缓存和协商缓存,直接请求最新资源。

CDN缓存(如果有的话)

参考 https://blog.csdn.net/HeyShHeyou/article/details/109194017

参考链接

https://www.cnblogs.com/vajoy/p/5341664.html

http 缓存 笔记的更多相关文章

  1. golang实现分布式缓存笔记(一)基于http的缓存服务

    目录 前言 cache 缓存服务接口 cache包实现 golang http包使用介绍 hello.go Redirect.go http-cache-server 实现 cacheHandler ...

  2. c#缓存 笔记

    1:缓存. 你需要了解大数据高并发的瓶颈在哪里,一般都是数据库层面的,机械硬盘承载不起非常快速的读写操作,cpu承载不起大量的逻辑运算,所以最基本的解决思路就是:1.换固态硬盘加快硬盘的读写效率.2. ...

  3. smarty之缓存笔记

    smarty缓存技术 在smarty中,缓存分为:普通缓存,单模版都缓存,局部缓存. 缓存:1:首选打开缓存配置项:$smarty->caching=true; 2:缓存生命周期的配置选项:$s ...

  4. .net4缓存笔记

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  5. SQL 笔记 By 华仔

    -------------------------------------读书笔记------------------------------- 笔记1-徐 最常用的几种备份方法 笔记2-徐 收缩数据 ...

  6. 分享一下我研究SQLSERVER以来收集的笔记

    分享一下我研究SQLSERVER以来收集的笔记 前言 为什麽分享??因为像现在网上很多人攻城师那样,转行去卖水果,卖早餐,总有一日我也会离开这个行业的 由于本人不是在大公司上班工资很低,我希望有一天存 ...

  7. MVC缓存OutPutCache学习笔记 (二) 缓存及时化VaryByCustom

    <MVC缓存OutPutCache学习笔记 (一) 参数配置> 本篇来介绍如何使用 VaryByCustom参数来实现缓存的及时化.. 根据数据改变来及时使客户端缓存过期并更新.. 首先更 ...

  8. MVC缓存OutPutCache学习笔记 (一) 参数配置

    OutPutCache 参数详解 Duration : 缓存时间,以秒为单位,这个除非你的Location=None,可以不添加此属性,其余时候都是必须的. Location : 缓存放置的位置; 该 ...

  9. [原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  10. PHP 开发 APP 接口 学习笔记与总结 - Redis 缓存

    Redis 可以定期将数据备份到磁盘中(持久化),同时不仅仅支持简单的key/value 类型的数据,同时还提供list,set,hash等数据结构的存储:Memcache 只是简单的key/valu ...

随机推荐

  1. Pod原理

    Pod 是 Kubernetes 集群中最基本的调度单元,我们平时在集群中部署的应用都是以 Pod 为单位的,而并不是我们熟知的容器,这样设计的目的是什么呢?为何不直接使用容器呢? 为什么需要 Pod ...

  2. Containerd和Docker的关系

    联系 容器运行时(Container Runtime)是Kubernetes(k8s)最重要的组件之一,负责管理镜像和容器的生命周期.Kubelet通过Container Runtime Interf ...

  3. ConfigMap使用说明

    ConfigMap概述 ConfigMap供容器使用的典型用法如下. (1)生成为容器内的环境变量. (2)设置容器启动命令的启动参数(需设置为环境变量). (3)以Volume的形式挂载为容器内部的 ...

  4. Nginx配置中一个不起眼字符"/"的巨大作用

    文章转载自:https://mp.weixin.qq.com/s/QwsbuNIqLpxi_FhQ5pSV3w Nginx作为一个轻量级的,高性能的web服务软件,因其占有内存少,并发能力强的特点,而 ...

  5. docker的cmd命令详解-前后台理解

    CMD 指令的格式和 RUN 相似,也是两种格式: shell 格式:CMD <命令> exec 格式:CMD ["可执行文件", "参数1", & ...

  6. Jupyter Notebook单元格加宽的方法3种

    Jupyter Notebook的代码单元格比较窄,在我的屏幕上只占了一半都不到,网络搜索下,共找到3种加宽的方法,总结一下. (一)只改变当前Jupyter笔记本的单元格宽度 在Jupyter No ...

  7. OpenJudge 1.6.7 有趣的跳跃

    07:有趣的跳跃 总时间限制: 1000ms 内存限制: 65536kB 描述 一个长度为n(n>0)的序列中存在"有趣的跳跃"当前仅当相邻元素的差的绝对值经过排序后正好是从 ...

  8. String类型变量的使用

    1.String属于引用数据类型,翻译为:字符串 2.声明String类型变量时,使用一对"" 3.String可以和8种基本数据类型变量做运算,且运算只能是连接运算:+ 4.运算 ...

  9. golang中经常会犯的一些错误

    0.1.索引 https://waterflow.link/articles/1664080524986 1.未知的枚举值 我们现在定义一个类型是unit32的Status,他可以作为枚举类型,我们定 ...

  10. JAVA系列之JVM内存调优

    一.前提 JVM性能调优牵扯到各方面的取舍与平衡,往往是牵一发而动全身,需要全盘考虑各方面的影响.在优化时候,切勿凭感觉或经验主义进行调整,而是需要通过系统运行的客观数据指标,不断找到最优解.同时,在 ...