什么是强缓存和协商缓存
什么是缓存
浏览器缓存就是把一个已经请求过的Web资源(如html页面,图片,js,数据等)拷贝一份副本储存在浏览器中。缓存会根据进来的请求保存输出内容的副本。当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个URL地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。
缓存有什么作用
浏览器缓存(BrowserCaching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的显示。
浏览器缓存优点:
①.减少网络带宽消耗
无论对于网站运营者或者用户,带宽都代表着金钱,过多的带宽消耗,只会便宜了网络运营商。当Web缓存副本被使用时,只会产生极小的网络流量,可以有效的降低运营成本。
②.降低服务器压力
给网络资源设定有效期之后,用户可以重复使用本地的缓存,减少对源服务器的请求,间接降低服务器的压力。同时,搜索引擎的爬虫机器人也能根据过期机制降低爬取的频率,也能有效降低服务器的压力。
③.减少网络延迟,加快页面打开速度
带宽对于个人网站运营者来说是十分重要,而对于大型的互联网公司来说,可能有时因为钱多而真的不在乎。那Web缓存还有作用吗?答案是肯定的,对于最终用户,缓存的使用能够明显加快页面打开速度,达到更好的体验。
浏览器缓存缺点:
在项目开发阶段因为缓存的原因导致资源没有及时更新而看不到最新的效果。

浏览器缓存又分为:强缓存和协商缓存两种。
强缓存
http1.0 的 expires
http1.0 中,通过头部字段 expires 定义缓存有效时间。expires 是一个绝对的日期。那么这个绝对值是取决于服务器,如果服务器和客户端的时间并不一致,那么就可能导致缓存过早失效或客户端使用已经过期的缓存。
http1.1 的 Cache-Control
为了解决这个问题,在http1.1中引入了Cache-Control字段,是最重要的规则,可以通过 max-age(单位为秒) 主要用于控制网页缓存,主要取值为:
Cache-Control 的值配置如下
请求头
- no-cache: 使用本地缓存必须向服务器验证
- no-store: 不缓存该请求的任何内容
- max-age: 响应的最大有效时间
- max-stale: 接受过期多久的缓存
- min-fresh: 期望在指定时间内的响应仍然有效
- no-transform: 代理不可更改媒体类型
- only-if-cached: 从缓存获取资源
- cache-extension:新指令的标记
响应头
- public: 任何机器都可以缓存。
- private: 只允许特定的人缓存。
- no-cache:要求客户端使用缓存时,必须向服务器确认。
- no-store:不允许任何缓存
- no-transform:代理不能更改媒体类型
- must-revalidate:可以缓存但是必须向服务器确认
- proxy-revalidate:中间代理必须对响应缓存的有效性再次确认
- max-age:最大缓存有效时间
- s-maxage:中间服务器最大缓存时间
- cache-extension:新指令标记
Cache-Control缓存原理
①.浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Cache-Control
②.浏览器在接收到这个资源后,会把这个资源连同所有response header一起缓存下来
③.浏览器再请求这个资源时,先从缓存中寻找,找到这个资源后,根据它第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行
④.如果缓存没有命中,浏览器直接从服务器加载资源时,Cache-Control Header在重新加载的时候会被更新
协商缓存
强缓存过期后,进入了协商缓存阶段。这个阶段目的在于,判断本地缓存是否还有效。如果有效则服务器会通知浏览器使用本地缓存。
通常,我们实现协商缓存有两种方式。
Last-Modified / IF-Modified-Since
- 通过
Last-modified/if-Modified-Since实现 - 当服务响应请求时,会将 Last-Modified 设置在响应头中,浏览器会记录该字段。
- 当该文件过期后,浏览器会将第一次收到的 Last-Modified 的值,设置到 请求头的 If-Modified-Since 字段中。
- 服务器收到请求,取出 If-Modified-Since 字段,与文件修改时间对比,如果没有改变就 返回 304(not modified),并更新浏览器缓存资源有效期。如果,不相同则返回该请求的资源。
- 缺点:只能判断秒级的改变,当变化文件在1秒以内,浏览器会认为缓存命中返回 304。为了解决这个问题,HTTP1.1 引入 ETag
Etag / IF-None-Match
- ETag 是通过 hash 算法,计算出来的文件唯一标识。当文件改变其计算出来的hash值也将是不同的。
- 当浏览器第一请求资源时,服务器会计算出文件的 hash 值,并将得到值 设置到响应头的 ETag 上。
- 浏览器接收响应,保存 ETag。当浏览缓存过期时,就将保存的 ETag 值,设置在 请求头的 If-None-Match 上。
- 服务器接收该请求,取出If-None-Match 值,并和服务器保存的文件进行 hash 比对。如果一样则 返回 304,并更新过期时间。不一样则返回新的文件。
- 缺点:
- hash 值的计算需要服务器的处理,如果用户量巨大。通过 ETag 进行协商缓存,对性能的浪费是巨大的。ETag 的出现并不是要代替 Last-Modified 的。
为什么要有 Etag
HTTP1.1 中 Etag 的出现主要是为了解决几个 Last-Modified 比较难解决的问题:
- 一些文件也许会周期性的更改,但是内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新 GET;
- 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说 1s 内修改了 N 次),
If-Modified-Since能检查到的粒度是秒级的,使用Etag就能够保证这种需求下客户端在 1 秒内能刷新 N 次 cache。 - 某些服务器不能精确的得到文件的最后修改时间。
协商缓存总结如下:
请求资源时,把用户本地该资源的 etag 同时带到服务端,服务端和最新资源做对比。
如果资源没更改,返回304,浏览器读取本地缓存。
如果资源有更改,返回200,返回最新的资源。
不能缓存的请求
当然并不是所有请求都能被缓存,无法被浏览器缓存的请求如下:
①.HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求;
②.需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的;
③.经过HTTPS安全加密的请求;
④.POST请求无法被缓存;
⑤.HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存;
用户行为对缓存的影响
| 用户操作 | Expires/Cache-Control | Last-Modied/Etag |
| 地址栏回车 | 有效 | 有效 |
| 页面链接跳转 | 有效 | 有效 |
| 新开窗口 | 有效 | 有效 |
| 前进回退 | 有效 | 有效 |
| F5 刷新 | 效(有争议,不同浏览器反馈不一致) | 有效 |
| Ctrl+F5 强制刷新 | 无效 | 无效 |
怎么设置强缓存与协商缓存
后端服务器如nodejs
res.setHeader('max-age': '3600 public')
res.setHeader(etag: '5c20abbd-e2e8')
res.setHeader('last-modified': Mon, 24 Dec 2018 09:49:49 GMT)
Nginx 配置
add_header Cache-Control "max-age=3600"
相关文章:
什么是强缓存和协商缓存
什么是缓存 浏览器缓存就是把一个已经请求过的Web资源(如html页面,图片,js,数据等)拷贝一份副本储存在浏览器中。缓存会根据进来的请求保存输出内容的副本。当下一个请求来到的时候,如果是相同的URL&#…...
算法刷题之堆
1. heapq 堆 Python 中只有最小堆: import heapqa [] heapq.heappush(a, 3) # 添加元素 heapq.heappush(a, 2) heapq.heappush(a, 1) while len(a): # 判断堆的长度print(heapq.heappop(a)) # 弹出堆顶元素# 将列表转换为最小堆 nums [2, 3, 1, 4, 5, 6] hea…...
javaweb导师选择系统
本文以JSP为开发技术,实现了一个导师选择系统。导师选择系统分为三大模块,包括管理员:学员信息管理、导师信息管理、导师选择管理、导师分布图、公告信息管理、系统管理,学生:个人资料管理、导师选择管理、导师分布图管…...
LeetCode150 逆波兰表达式求值
题目: 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算符为 ‘’、‘-’、‘*’ 和 ‘/’ 。每个操作数(运算对象)都可以…...
【Node.js】项目开发实战(中)
开发用户的注册和登录接口步骤1,打开MySQL Workbench,打开自己的数据库进入创建用户信息表新建 ev_users表安装并配置mysql模块安装mysql模块新建db文件夹下index.js,导入并配置mysql模块安装bcryptjs对密码进行加密处理新建/router_handler/user.js中&a…...
记录一次 New Bing 英语陪练
记录一次 New Bing 英语陪练 Now I start to speak english to chat with you . Help me find the mistake in my word and help me improve my english I’m glad you want to practice your English with me. I can help you find the mistakes in your words and help you i…...
【Python】照片居然能变素描?不会画画但是咱会代码
文章目录前言一、准备二、下载预训练模型总结前言 Photo-Sketching 一个能将照片的轮廓识别出来并将其转化为“速写”型图像的开源模块。 比如,这只小狗: 经过模型的转化,会变成卡通版的小狗: 非常秀,这很人工智能…...
已解决正确配置git环境变量
已解决git没有配置环境变量,抛出异常ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH?,附上正确配置git环境变量的教程 文章目录报错问题报错翻译报错原因解决方法《100天精通Python》专栏推荐白嫖80g Python全栈…...
【逐步剖C】-第十章-自定义类型之结构体、枚举、联合
一、结构体 前言:有关结构体的声明、定义、初始化以及结构体的传参等结构体的基本使用在文章【逐步剖C】-第六章-结构体初阶中已进行了详细的介绍,需要的朋友们可以看看。这里主要讲解的是有关结构体的内存问题。 1. 结构体的内存对齐 (1&…...
Windows Server 2016 中文版、英文版下载 (updated Mar 2023)
Windows Server 2016 Version 1607,2023 年 3 月更新 请访问原文链接:https://sysin.org/blog/windows-server-2016/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 本站将不定期发布官方原版风格月度更…...
Linux 4G 通信实验
目录4G 网络连接简介高新兴ME3630 4G 模块实验ME3630 4G 模块简介ME3630 4G 模块驱动修改ME3630 4G 模块ppp 联网测试前面我们学习了如何在Linux 中使用有线网络或者WIFI,但是使用有线网络或者WIFI 有 很多限制,因为要布线,即使是WIFI 你也得…...
华为OSPF技术详细介绍,保姆级,谁都能看懂(一)
目录 1、简介 2、OSPF基本原理 3、OSPF的特点 4、OSPF区域 5、路由器的类型 6、OSPF5种报文 7、后半部分内容 1、简介 OSPF(Open Shortest Path First,开放最短路径优先)是一个基于链路状态的内部网关协 议。目前针对IPv4协议使用的是OS…...
行人车辆检测与计数系统(Python+YOLOv5深度学习模型+清新界面)
摘要:行人车辆检测与计数系统用于交通路口行人及车辆检测计数,道路人流量、车流量智能监测,方便记录、显示、查看和保存检测结果。本文详细介绍行人车辆检测,在介绍算法原理的同时,给出Python的实现代码、PyQt的UI界面…...
SM3哈希算法的FPGA实现 I
SM3哈希算法的FPGA实现 I SM3哈希算法的FPGA实现 I一、什么是SM3哈希算法?二、SM3哈希算法的具体内容1、填充2、迭代与压缩3、计算拼凑值三、参考文档语言 :verilog 仿真工具: Modelsim EDA工具:quartus II 一、什么是SM3哈希算法…...
【数据结构与算法】线性表--数组
文章目录一、前言二、数组的概念三、数组的操作数组的插入数组的删除四、容器与数组五、问题:为何数组要从0开始编号,而不是1开始呢?六、总结一、前言 常见的数据结构如下图,本文主要讲解数据结构线性表--数组。 二、数组的概念 …...
剑指offer排序专题
剑指offer排序专题 jz3 数组中重复的数字描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组[…...
已解决Cannot open D:\Soft\Python36\Scripts\pip3-script.py
已解决Cannot open D:\Soft\Python36\Scripts\pip3-script.py 文章目录报错问题报错翻译报错原因解决方法1:easy_install 来安装pip解决方法2:本地安装pip《100天精通Python》专栏推荐白嫖80g Python全栈视频报错问题 粉丝群里面的一个小伙伴遇到问题…...
3 步走,快速上手 API 接口测试
开始 API 接口测试之前,我们需要弄清接口测试的含义: 接口测试就是根据接口清单,模拟客户端向服务端发送请求数据,并获取响应数据后,查看响应数据是否符合预期的过程。 整个过程可以分为三个步骤: 第一步&…...
爬虫-day1-正则表达式作业
利用正则表达式完成下面的操作: 一、不定项选择题 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括(ABD ) A. r"\(?\d{3}\)?-?\d{8}" B. r"[0-9()-]" C. r"[0-9(-)]*\d*&…...
【半监督医学图像分割 2023 CVPR】RCPS
文章目录【半监督医学图像分割 2022 CVPR】RCPS摘要1. 介绍2. 相关工作2.1 医学图像分割2.1 半监督学习2.3 对比学习3. 方法3.1 整体概述3.2 纠正伪监督3.3 双向Voxel对比学习。4. 实验【半监督医学图像分割 2022 CVPR】RCPS 论文题目:RCPS: Rectified Contrastive …...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
