简析强制缓存和协商缓存

news2025/7/9 14:49:52

零、目录

  1.   背景介绍
  2.   http 缓存机制
  3.   使用小结

一、 背景介绍

        浏览器和服务器进行交互的过程, 时间开销的瓶颈往往出现在数据的传输的过程之中。

        这个场景类似介于 A城B城 之间只有一座 “通道” , 每次想从A城B城 ,必须按照人数交付高昂的路费, 那么如果要减少这种高昂的路费开销的话, 核心思想就是尽可能的减少通过这座 “通道” 的次数又或者减少通过这座通道的“人数”。基于这种理念,在 http协议的基础上, 提出了一种协议缓存, 这种协议缓存又可以细分为 强制缓存协商缓存 两种,分别对应上述减少过桥次数减少过桥人数的理念。

二、http缓存机制简介

        1. 强制缓存

        强制缓存的思想是,在浏览器内置数据库中缓存每次请求中 “可以被缓存” (受到一些关键字的管控)的静态资源如 image, css, js 文件, 当第二次请求被缓存过的资源时候,会通过校验两个字段 ExpiresCache-Controlmax-age字段(注意,Expires http1.0 的产物, Cache-Control 则是 http1.1 的产物。 两者同时存在, 或者只存在其中之一, 都可以触发强制缓存

  • 当满足字段约束的情况下, 浏览器就不会向服务器发送请求而是直接从服务器返回数据, 同时其状态码为 200

  • 当不满足字段约束的情况下, 浏览器则会向服务器正常发送请求, 具体流程可见图(01.强制缓存示意图)

                       (01.强制缓存示意图)    

        强制缓存主要取决于两个字段 ExpiresCache-Control 中的 max-age 字段, 在两个响应头都存在的情况下, 其流程如图 (02. 强制缓存执行流程图)所示 

(02. 强制缓存执行流程图)        

        如图(02. 强制缓存执行流程图)可知, 当两个字段同时存在得到时候, Cache-Control 中的 max-age 字段字段优先级会稍微高一点, 当 Cache-Control 中的 max-age 字段校验成功,会直接返回浏览器内置数据库的缓存, 失效时才会将决策权传递给 Expires 字段判断。

        这样设计的原因,大概是因为 Expires 字段在设计时存在了这么一个缺陷——Expires字段返回的是服务器的时间, 而非客户端的本机时间。 当存在时差, 或者客户修改本地时间的情况下 Expires 字段会存在失效的可能性,比如 当同一时刻下服务器时间为 2022/4/26 06:00:00 客户端时间为 2022/4/26 12:00:00 过期时间为两个小时之后, 则服务器会返回 2022/4/26 08:00:00 这个时间对应的值。由于浏览器运行在客户环境下,对于客户而言, 这个缓存已经过期了,虽然缓存确实有效, 但是对于浏览器而言这个缓存确确实实是 “过期了”, 这会导致强制缓存永远不会生效

        那么为了解决这个问题, http 1.1 协议中添加了 Cache-Control 中的 max-age, 他是一个相对值, 即客户端获取到这个文件多少秒后失效, 其判别权力全权交由浏览器, 这会相对更准确些。

        2. 协商缓存

        协商缓存主要由 ETagLast-Modified 两个字段来实现

  • ETag 是一个用于映射 web 资源的映射 token,这个 token 应该满足唯一对应到一 个web服务器上的静态资源(具体实现通常是提取文件相关信息进行hash和base64编码等操作)

  • Last-Modified 则通常是文件最后更新的日期时间戳

(通过上述两个字段就可以判断当前文件是否是最新的数据)

    与上述两个字段配对的分别是 If-None-Match If-Modified-Since 这两个字段, 具体流程如下图所示(03. 协商缓存示意图)

       (03. 协商缓存示意图) 

        浏览器首次向服务器请求数据 A, 服务器正常返回数据,同时在响应头中放入 ETagLast-Modified 两个新字段。

        当浏览器第二次向服务器请求数据 A 时, 浏览器会自动地在请求头附上 If-None-MatchIf-Modified-Since 两个字段(分别对应的是 ETagLast-Modified 的值,两两相等), 然后由服务器端进行校验, 校验通过的话(表明数据有效), 服务器会直接返回 状态码 304 ,且不携带响应体的报文段, 这相当于告诉浏览器:当前缓存有效, 可以直接使用! 校验失败则会和首次请求一样, 返回状态码为200且携带数据响应体的报文段, 同时这个响应头会带上新的ETagLast-Modified, 为下一次协商缓存做好铺垫 。

        需要注意的是, 在不用框架的情况下, 协商缓存需要由后端开发人员手动实现,因此 ETagLast-Modified 两个字段的优先级取决于开发者, 但是 Last-Modified 这个字段可以记录的时间戳精确度是有一定限制的,如果连续多次数据更新在精确度范围外, 会产生精确度丢失, 因此通常会让ETag 的优先级高于 Last-Modified 字段(类似于Cache-controlmax-age一样, 属于是后续改进协议的一个新字段, 因此优先级一般会高点)

        3. 强制缓存 + 协商缓存

        了解了 强制缓存 协商缓存, 我们不妨看看两者并存的情况,如图(04. 强制缓存和协商缓存联合)所示

 (04. 强制缓存和协商缓存联合)

        默认情况下, 浏览器会优先考量强制缓存的情况, 当强制缓存生效的情况下, 请求并不会到达服务器, 因此也就不会触发协商缓存。 当强制缓存失效的时候, 浏览器便会将请求传递到服务器, 于是服务器又会开始校验 If-Modified-SinceIf-None-math 两个字段, 重复上述协商缓存的一个执行流程

        乍一看,两者并存的情况, 有点像是两个协议的简单叠加,此时的协商缓存更像是强制缓存的兜底策略, 很可能协商缓存很长一段时间都不会生效(强制缓存过期时间设置过长的情况下), 因为强制缓存的优先级是要高于协商缓存的。 当然这并不是我们想看到的, 比方说当后端数据确实变更了, 而此时的浏览器由于使用了强制缓存,则会出现数据不一致的情况, 因此在这里引入了请求头中的两个字段 no-cache, 当使用了 no-cache 字段的时候, 浏览器将不再使用强制缓存, 而是直接去请求服务器, 这个时候就会用到协商缓存了(顺带一提的是, 还有一个 no-store 字段, 用了这个字段浏览器则不会在使用缓存的数据也不缓存数据,即强制缓存和协商缓存都失效了)

        4. 缓存机制之间的一些区别

  1. 强制缓存在缓存有效的情况下不会去请求服务器, 其数据来源则是浏览缓存的本地磁盘。而协商缓存会向服务器请求,但是在协商缓存成功的情况下, 服务器只会返回一个不带响应体的报文,结合开头的背景来说 强制缓存选择“减少过桥次数”的策略, 而协商缓存则是采用 ‘减少过桥人数’的策略
  2. 强制缓存在浏览器强制刷新的情况下不会生效, 而协商缓存则不受影响。(调试代码测试时候,要注意)
  3. 强制缓存返回的报文状态码为 200, 协商缓存返回的报文状态码为 304 (前端使用fetch请求的情况, 协商缓存的 状态码304 会转成 200)
  4. 强制缓存发生在浏览器端, 协商缓存发生在服务器端

三、使用小结

         强制缓存协商缓存需要具体条件下来用, 下边是笔者总结的几个小点

  1.     强制缓存存在一个瓶颈, 当浏览器用户强刷新时,浏览器会直接跳过强制缓存, 这点不注意很容易会被忽视掉。
  2.     强制缓存不适合 SPA 应用的入口文件, 因为重新部署后, 用户如果没有强制刷新, 则无法在第一时间内看到新的网页内容。
  3.    作为一个前端开发者可以通过设置请求头中的 no-cacheno-store 字段选择使用协商缓存或者不使用缓存!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/406535.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Maven使用教程(IDEA版)

目录 一、Maven简介 1.1 在项目中如何导入jar包? 1.2 传统导入jar包的方式存在什么问题? 1.3 项目生命周期 1.4 Maven简介 二、Maven安装及配置 2.1 Maven下载 2.2 Maven安装 2.3 配置环境变量 三、Maven的项目结构 3.1 Maven的项目结构 3.2…

【CSS】CSS 特性 ③ ( CSS 优先级 | 优先级引入 | 选择器基本权重 )

文章目录一、CSS 优先级1、优先级引入2、选择器基本权重3、完整代码示例一、CSS 优先级 1、优先级引入 定义 CSS 样式时 , 可能出现 多个 类型相同的 规则 定义在 同一个元素上 , 如果 CSS 选择器 相同 , 执行 CSS 层叠性 , 根据 就近原则 选择执行的样式 , 如 : 出现两个 div…

VueX使用

vuex基本概念 vuex官方文档 vuex是vue的状态管理工具,状态即数据。 状态管理就是集中管理vue中 通用的 一些数据 注意(官方原文): 不是所有的场景都适用于vuex,只有在必要的时候才使用vuex 使用了vuex之后&#xf…

手机解锁方法:8个顶级的 Android 手机解锁软件

一般来说,太简单的密码是不安全的,所以我们设置一个安全的密码,可能会稍微复杂一点。然而,我们可能经常会忘记复杂的密码并锁定我们的 Android 智能手机。 8个顶级的 Android 手机解锁软件 如果您遇到过这种情况并且正在寻找一种…

【vue2】vue全家桶介绍,学习vue必备

​ 🥳博 主:初映CY的前说(前端领域) 🌞个人信条:想要变成得到,中间还有做到! 🤘本文核心:vue全家桶介绍,学习vue必备!!! 【前言…

Vue开发实例(11)之el-menu实现左侧菜单导航

作者简介 作者名:编程界明世隐 简介:CSDN博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注&…

【Vue从入门到进阶】Node.js安装与配置

✅作者简介:CSDN一位小博主,正在学习前端,欢迎大家一起来交流学习🏆 📃个人主页:白月光777的CSDN博客 🔥系列专栏:Vue从入门到进阶 💬个人格言:但行好事&…

OpenAI 发布GPT-4——全网抢先体验

OpenAI 发布GPT-4 最近 OpenAI 犹如开挂一般,上周才刚刚推出GPT-3.5-Turbo API,今天凌晨再次祭出GPT-4这个目前最先进的多模态预训练大模型。与上一代GPT3.5相比,GPT-4最大的飞跃是增加了识图能力,并且回答准确性也得到显著提高。…

使用SpringBoot一小时快速搭建一个简单后台管理(后端篇)

不好意思让大家久等啦,最近也是因为学期末了,事情多了一点,所以更新的比较慢,请大家谅解下~ 好了话不多说,进入今天的教程环节 本次案例一共两篇文章教学: (第一篇):数据…

聊聊vue3的defineProps、defineEmits、defineExpose

最近在开发中用到了vue3的defineProps、defineEmits和defineExpose&#xff0c;感觉发现新大陆一般&#xff0c;所以利用闲碎时间对这三个方法做个总结。 defineProps const props defineProps<{foo: String,bar?: Number }>()defineProps 是vue3的写法并且是一个仅 …

Video.js 使用教程 - 手把手教你基于 Vue 搭建 HTML 5 视频播放器

本文首发&#xff1a;《Video.js 使用教程 - 手把手教你基于 Vue 搭建 HTML 5 视频播放器》 Video.js 是最强大的网页嵌入式 HTML 5 视频播放器的组件库之一&#xff0c;也是大多数人首选的网页视频播放解决方案。复杂的网页视频渲染&#xff0c;在引入 Video.js 后&#xff0…

idea连接SQL Server数据库

数据库配置 1.安装数据库&#xff1a;自行安装 我的SQL Server版本为2019 2.登录数据库&#xff0c;登陆方式有两种&#xff0c;连接数据库选择SQLServer身份验证 1.windows登录&#xff0c;直接登录 2.SQLServer登录&#xff0c;需要输入用户名和密码&#xff0c;默…

【Vant Weapp】van-cell 单元格

目录 自定义内容​​​​​​​ 自定义右侧value&#xff08;姓名手机号&#xff09; 自定义右侧value&#xff08;文件预览&#xff09; 自定义下方label描述信息 真机border相当明显 修改样式&#xff08;下边框、文字&#xff09; 循环列表中的cell 自定义内容 自定义…

前端必学 - 大文件上传如何实现

前端必学 - 大文件上传如何实现写在前面问题分析开始操作一、文件如何切片二、得到原文件的hash值三、文件上传四、文件合并技术点总结【重要】一、上传文件&#xff1f;二、显示进度三、暂停上传四、Hash有优化空间吗&#xff1f;五、限制请求个数六、拥塞控制&#xff0c;动态…

Vue+element ui实现好看的个人中心

目录一、效果图二、项目结构三、界面效果和代码实现1.路由注册2.个人主页实现3.编辑弹窗按钮实现4.个人简介实现5.发贴页实现6.收藏页实现7.关注和收藏页实现四、总结一、效果图 仿照原神社区的个人中心写了个个人中心界面&#xff0c;下图分别为原神社区个人中心主页和我画的…

vue项目天地图使用

最近的项目中遇到了新的需求&#xff0c;需要在项目中使用天地图&#xff0c;因为第一次接触&#xff0c;官方的网站引用之类的也没有进行详细的介绍&#xff0c;自己去找的时候发现这部分的文章也比较少&#xff0c;有的问题也没有讲清楚&#xff0c;所以发布这篇文章分享总结…

关于将tomcat卸载干净

这学期我们开始学习Java Web技术&#xff0c;要求安装tomcat&#xff0c;我到官网上下载的时候不小心下载了最新的测试版&#xff0c;但是安装的eclipse无法配置最新班的tomcat&#xff0c;就开启了我的下载、卸载之旅&#x1f62d;&#x1f62d; 在此之前也有在网上找了很多相…

小程序怎么自定义导航栏,导航栏放图片、设置高度

今天来说一下小程序的自定义导航栏。 1、设置导航栏style为custom&#xff1a; 2、这是刷新页面&#xff0c;页面的内容就跑到了页面的顶端&#xff0c;不留丝毫间隙&#xff1a; 3、然后定义一个components&#xff0c;就是我们自定义的导航栏组件&#xff1a; &#xff…

Vue3 + Element Plus 按需引入 - 自动导入

文章目录1 前言1.1 目的1.2 最终效果2 准备工作3 按需引入3.1 安装插件3.2 修改 vite.config.ts 文件4 其他4.1 ElMessageBox 使用时报错4.1.1 Eslint 报错&#xff1a; ElMessageBox is not defined.eslint(no-undef)4.1.2 TS 报错&#xff1a; Cannot find name ElMessageBox…

html设置背景颜色以及背景图片

背景颜色 backgroud-color:transparent color transparent : 背景色透明 color : 指定背景颜色 直接设置标签的style属性&#xff08;行内样式&#xff09; 例&#xff1a;将这个段落的背景设为红色 用选择器进行设置&#xff08;内嵌样式、外链样式&#xff0…