深入理解 HTTP 缓存
浏览器缓存不是本地存储,要分清。浏览器缓存分为强缓存和协商缓存。本篇文章参考:使用 HTTP 缓存防止不必要的网络请求
讲解之前,我画了个简图来解释浏览器从缓存中获取资源的过程。
1. 强缓存
强缓存是浏览器缓存机制中的一种,它允许浏览器对之前请求过的资源进行缓存,并在下一次请求时直接使用缓存的资源,而不需要再次向服务器发送请求。这种方式可以有效地减少带宽消耗、降低服务器压力,并提高页面的访问速度。
强缓存的实现依赖于HTTP响应头中的特定字段,主要是Expires
和Cache-Control
。
-
Expire:这个响应头在 Http 1.0 中提出(如果浏览器不支持HTTP1.1,则用expires判断是否过期),它表示资源的过期时间,即一个绝对时间戳。浏览器会将该时间与当前时间进行比较,如果当前时间在Expires之前,浏览器就会直接从本地缓存中获取资源,而不会再次向服务器发起请求。但是,Expires存在一些局限性,例如它受到客户端时间的影响,如果客户端的时间被更改,缓存可能会失效。
-
Cache-Control:在HTTP 1.1版本中,引入了Cache-Control响应头来提供更灵活的缓存控制机制。这个字段可以设置多个指令,包括
max-age
、public
、private
、no-cache
、no-store
等。其中,max-age
指令表示资源在缓存中的最大有效时间,是一个相对时间值。浏览器会根据这个值来决定是否使用缓存资源。如果同时存在Expires和Cache-Control,Cache-Control的优先级高于Expires。
以下 Cache-Control
值可帮助您微调无版本控制网址的缓存位置和方式:
no-cache
。这会指示浏览器必须在每次使用网址的缓存版本之前向服务器重新验证。no-store
。这会指示浏览器和其他中间缓存(如 CDN)绝不存储文件的任何版本。private
。浏览器可以缓存文件,但中间缓存无法缓存。public
。任何缓存都可以存储响应。
当浏览器请求一个资源时,它会首先检查本地缓存中是否有该资源,并且该资源是否还在有效期内。如果是,浏览器就会直接使用缓存资源,而不会向服务器发送请求。这就是强缓存的工作原理。
需要注意的是,强缓存虽然可以提高性能,但也可能导致一些问题。例如,如果服务器上的资源已经更新,但由于缓存的存在,客户端可能无法获取到最新的资源。因此,在设计缓存策略时,需要权衡性能和资源更新的需求。
2.1. 强缓存缺点
假设您的服务器指示浏览器将某个 CSS 文件缓存 1 年 (Cache-Control: max-age=31536000
),但设计人员刚刚进行了一项紧急更新,您需要立即发布这项更新。
如何通知浏览器更新文件的“过时”缓存副本? 您无法更改资源,至少不能更改资源的网址。浏览器缓存响应后,缓存版本将一直使用,直到它不再处于最新状态(由 max-age
或 expires
确定),或由于某种其他原因(例如,用户清除了浏览器缓存)从缓存中逐出为止。
因此,在构建网页时,不同的用户可能最终使用的是文件的不同版本:刚刚获取了资源的用户使用的是新版本,而缓存了较早(但仍有效)副本的用户使用的是旧版本的响应。
如何才能做到两全其美:客户端缓存和快速更新?您可以更改资源的网址,并在资源内容发生变化时强制用户下载新响应。通常情况下,可以通过在文件名中嵌入文件的指纹或版本号(例如 style.x234dff.css
)来实现此目的。
2. 协商缓存
协商缓存是浏览器与服务器之间的一种缓存验证机制。当浏览器发出资源请求时,如果本地缓存失效或者没有命中强缓存,浏览器会使用协商缓存来与服务器进行“商量”,判断资源是否更新,进而决定是否使用本地缓存。
协商缓存主要依赖于请求头中的某些字段和服务器返回的响应头中的特定字段来进行判断。主要的请求头字段有If-Modified-Since
和If-None-Match
,而主要的响应头字段则有Last-Modified
和ETag
。
- If-Modified-Since:这是一个请求头字段,它包含了浏览器上次请求该资源时服务器返回的
Last-Modified
字段的值。当浏览器再次请求该资源时,会将这个值放在If-Modified-Since
请求头中发送给服务器。服务器会比较这个时间戳与资源在服务器上的最后修改时间,如果资源未被修改,则服务器会返回304状态码,告诉浏览器可以继续使用本地缓存;如果资源已被修改,则服务器会返回新的资源以及200状态码。 - If-None-Match:这是另一个请求头字段,它包含了浏览器上次请求该资源时服务器返回的
ETag
字段的值。ETag
是一个Web服务器为每个资源分配的唯一标识符,用于判断资源是否更新。当浏览器再次请求该资源时,会将这个ETag
值放在If-None-Match
请求头中发送给服务器。服务器会比较这个ETag
值与当前资源的ETag
值,如果相同,说明资源未更新,服务器返回304状态码;如果不同,说明资源已更新,服务器返回新的资源以及200状态码。
在响应头中,服务器会使用Last-Modified
和ETag
字段来告诉浏览器资源的最后修改时间和唯一标识符。当浏览器下次请求该资源时,会利用这些值来进行协商缓存的判断。
需要注意的是,如果请求中同时包含了If-Modified-Since
和If-None-Match
字段,服务器会优先验证If-Modified-Since
请求头,然后再验证If-None-Match
。只有当这两个验证都通过时,服务器才会返回304状态码,否则将返回新的资源和200状态码。(关于服务器是先验证 If-Modified-Since 还是 If-None-Match 并没有准确的顺序,甚可能只验证其中一个)。
建议使用 ETag:
ETag
和 Last-Modified
的用途相同:确定浏览器是否需要重新下载已过期的缓存文件。建议使用 ETag
方法,因为它更准确。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度。
3. 使用场景
强缓存和协商缓存各有其适用的场景,它们的选择主要基于资源的更新频率、访问性能需求以及网络条件等因素。
强缓存的适用场景:
- 资源更新不频繁:当服务器上的资源更新不频繁时,使用强缓存是合适的。因为强缓存允许浏览器直接使用本地缓存的副本,无需向服务器发起请求,这可以显著提高访问速度和降低服务器压力。
- 对性能要求较高:对于需要快速加载和渲染的页面或资源,使用强缓存可以显著提高用户体验。
协商缓存的适用场景:
- 资源更新较频繁:当服务器上的资源更新较为频繁时,使用协商缓存更为合适。因为协商缓存会在每次请求时与服务器进行“商量”,检查资源是否已更新。如果资源已更新,服务器会返回新的资源;如果资源未更新,服务器则返回304状态码,告诉浏览器继续使用本地缓存。
- 对实时性要求较高:对于需要确保用户始终获取到最新资源的场景,如新闻网站、实时数据展示等,协商缓存可以确保客户端与服务器之间的数据同步。
在实际应用中,通常会根据资源的特性和业务需求来综合选择使用强缓存还是协商缓存,或者结合使用两者以达到最佳的缓存效果。同时,还需要注意缓存过期时间的设置,以避免因缓存过期而导致的问题。
相关文章:

深入理解 HTTP 缓存
浏览器缓存不是本地存储,要分清。浏览器缓存分为强缓存和协商缓存。本篇文章参考:使用 HTTP 缓存防止不必要的网络请求 讲解之前,我画了个简图来解释浏览器从缓存中获取资源的过程。 1. 强缓存 强缓存是浏览器缓存机制中的一种,…...

upload-labs 通关方法
目录 Less-1(JS前端验证) Less-2(MIME验证) Less-3(黑名单,特殊过滤) Less-4(黑名单验证,.htaccess) Less-5(黑名单,点空格点绕过…...
5-26 Cpp学习笔记
1、如果子类实现了基类的函数,返回值、参数都相同,就覆盖了基类的函数。 2、使用作用域解析运算符来调用基类的函数。myDinner.Swim(); —— 调用子类的。myDinner.Fish::Swim(); —— 调用基类的(基类是Fish) 3、在子类中使用关键字using解除对Fish::…...

YOLOv8_pose的训练、验证、预测及导出[关键点检测实践篇]
1.关键点数据集划分和配置 从上面得到的数据还不能够直接训练,需要按照一定的比例划分训练集和验证集,并按照下面的结构来存放数据,划分代码如下所示,该部分内容和YOLOv8的训练、验证、预测及导出[目标检测实践篇]_yolov8训练测试验证-CSDN博客是重复的,代码如下: …...

架构师必考题--软件系统质量属性
软件系统质量属性 1.质量属性2.质量属性场景描述3.系统架构评估 这个知识点是系统架构师必考的题目,也是案例分析题第一题, 有时候会出现在选择题里面,考的分数也是非常高的。 1.质量属性 属性说明可用性错误检测/恢复/避免性能资源需求/管理…...

使用AWR对电路进行交流仿真---以整流器仿真为例
使用AWR对电路进行交流仿真—以整流器仿真为例 生活不易,喵喵叹气。马上就要上班了,公司的ADS的版权紧缺,主要用的软件都是NI 的AWR,只能趁着现在没事做先学习一下子了,希望不要裁我。 本AWR专栏只是学习的小小记录而…...
在UbuntuLinux系统上安装MySQL和使用
前言 最近开始计划在Ubuntu上写一个webserver的项目,看到一些比较好的类似的项目使用了MySQL,我就打算先把环境搞好跑一下试试,方便后面更进一步的学习。其实在本机windows上我已经有一个mysql,不过 在Unbuntu上安装MySQL 首先…...
React 如何自定义 Hooks
自定义 Hooks React 内部自带了很多 Hooks 例如 useState、useEffect 等等,那么我们为什么还要自定义 Hooks?使用 Hooks 的好处之一就是重用,可以将代码从组件中抽离出来定义为 Hooks,而不用每个组件中重复去写相同的代码。首先是…...

智能家居完结 -- 整体设计
系统框图 前情提要: 智能家居1 -- 实现语音模块-CSDN博客 智能家居2 -- 实现网络控制模块-CSDN博客 智能家居3 - 实现烟雾报警模块-CSDN博客 智能家居4 -- 添加接收消息的初步处理-CSDN博客 智能家居5 - 实现处理线程-CSDN博客 智能家居6 -- 配置 ini文件优化设备添加-CS…...
双指针用法练习题(2024/5/26)
1三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元…...

Ansible02-Ansible Modules模块详解
目录 写在前面4. Ansible Modules 模块4.1 Ansible常用模块4.1.1 Command模块4.1.2 shell模块4.1.3 scrpit模块4.1.4 file模块4.1.5 copy模块4.1.6 lineinfile模块4.1.7 systemd模块4.1.8 yum模块4.1.9 get_url模块4.1.10 yum_repository模块4.1.11 user模块4.1.12 group模块4.…...

【Python特征工程系列】一文教你使用PCA进行特征分析与降维(案例+源码)
这是我的第287篇原创文章。 一、引言 主成分分析(Principal Component Analysis, PCA)是一种常用的降维技术,它通过线性变换将原始特征转换为一组线性不相关的新特征,称为主成分,以便更好地表达数据的方差。 在特征重要…...
【Linux】Ubuntu系统挂载NAS文件夹
测试系统:Ubuntu24.02 1. 安装必要的软件包 sudo apt update sudo apt install cifs-utils 2. 创建挂载点 sudo mkdir -p /mnt/nas 3. 获取当前用户的 UID 和 GID id -u id -g 4. 挂载:设置用户名/密码/nas地址 sudo mount -t cifs -o username,…...

如何用ai打一场酣畅淋漓的数学建模比赛? 给考研加加分!
文章目录 数学建模比赛1. 数学建模是什么?2. 数学建模分工合作2.1 第一:组队和分工合作2.2 第二:充分的准备2.3 第三:比赛中写论文过程 3. 数学建模基本过程4. 2023全年数学建模竞赛时间轴5. 数学建模-资料大全6. 数学建模实战 数…...

深入浅出MySQL事务实现底层原理
重要概念 事务的ACID 原子性(Atomicity):即不可分割性,事务中的操作要么全不做,要么全做一致性(Consistency):一个事务在执行前后,数据库都必须处于正确的状态…...

SVM兵王问题
1.流程 前面六个就是棋子的位置,draw就是逼和,后面的数字six就代表,白棋最少用六步就能将死对方。然后呢,可以看一下最后一个有几种情况: 2.交叉测试 leave one out: 留一个样本作测试集,其余…...
yolov5_obb
yolov5_obb: 旋转目标检测从数据制作到终端部署全流程教学...

NextJs 初级篇 - 安装 | 路由 | 中间件
NextJs 初级篇 - 安装 | 路由 | 中间件 一. NextJs 的安装二. 路由2.1 路由和页面的定义2.2 布局的定义和使用2.3 模板的定义和使用① 模板 VS 布局② 什么是 use client 2.4 路由跳转的方式2.5 动态路由2.6 路由处理程序① GET 请求的默认缓存机制② 控制缓存或者退出缓存的手…...

变分自动编码器(VAE)深入理解与总结
本文导航 0 引言1 起源1.1 自编码器的任务定义1.2 自编码器存在的问题1.3 VAE的核心思路 2 VAE的建模过程2.1 VAE的任务定义2.2 真实分布 ϕ \phi ϕ是什么,为什么要逼近这个分布的参数,如何做?2.3 “重参数化(Reparameterization…...

Leetcode 剑指 Offer II 079.子集
题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个整数数组 nums ,数组中的元素 互不相同 。返…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...