HTTP缓存机制与原理详解

article/2025/9/11 4:57:37

1.1 - 缓存

  • 缓存可以重用已获取的资源能够有效的提升网站与应用的性能。
  • Web 缓存能够减少延迟与网络阻塞,进而减少显示某个资源所用的时间。
  • 借助 HTTP 缓存,Web 站点变得更具有响应性。
  • 缓存分为两点:强制缓存和协商缓存

1.2 - 强制缓存

  • 概念
    • 强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。
    • 简单来讲就是强制浏览器使用当前缓存
    • 所请求的数据在缓存数据库中尚未过期时,不与服务器进行交互,直接使用缓存数据库中的数据。当缓存未过期时基本流程如下:
      强制缓存.jpg
  • 实现:通过服务器端设置响应头字段来控制强制缓存的过期时间
    • expires (http1.0) 其指定了一个日期/时间, 在这个日期/时间之后,HTTP响应被认为是过时的。但是它本身是一个HTTP1.0标准下的字段,所以如果请求中还有一个置了 “max-age” 或者 “s-max-age” 指令的Cache-Control响应头,那么 Expires 头就会被忽略。
    • cache-control (http1.1) 通用消息头用于在http 请求和响应中通过指定指令来实现缓存机制。
    • cache-control 优先级比 expires 高
  • expires
    • 日期(new Date().toGMTString()) 缓存的最大有效时间
  • cache-control
    • max-age(单位s) 缓存的最大有效时间
    • no-cache 使用协商缓存
    • no-store 不使用任何缓存
    • public (客户端、代理服务器)缓存所有资源
    • private 默认值,只有客户端缓存所有资源
  • 比如 jQuery 用强制缓存(长久不变,读取不了新东西),因为变化慢,还有一些图片,一直变,有些广告变动很快,就走协商缓存。

1.3-协商缓存

  • 概念
    • 协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
    • 当强缓存过期未命中或者响应报文Cache-Control中有must-revalidate标识必须每次请求验证资源的状态时,便使用协商缓存的方式去处理缓存文件。
      协商缓存主要原理是从缓存数据库中取出缓存的标识,然后向浏览器发送请求验证请求的数据是否已经更新,如果已更新则返回新的数据,若未更新则使用缓存数据库中的缓存数据,具体流程如下,当协商缓存命中:

协商缓存.jpg- 实现:

  • Last-Modified / If-Modified-Since
  • Etag / If-None-Match
  • Etag / If-None-Match 优先级比 Last-Modified / If-Modified-Since 高。
  • Last-modified
    • 记录服务器返回资源的最后修改时间
    • 由客户端发送给服务器
  • If-Modified-Since
    • 记录服务器返回资源的最后修改时间
    • 由服务器发送给客户端
  • Etag
    • 当前文件的唯一标识(由服务器生成)
    • 由客户端发送给服务器
  • If-None-Match
    • 当前文件的唯一标识(由服务器生成)
    • 由服务器发送给客户端
  • 工作流程:
    • 第一次:由服务器返回 If-None-Match 和 If-Modified-Since 字段通过响应头方式返回
    • 第二次:下次浏览器请求时,携带了Etag(值为上一次的If-None-Match的值)和 Last-modified(值为上一次的If-None-Since的值)发送给服务器
    • 服务器先检查Etag是否等于最新的If-None-Match的值,如果相等直接走浏览器本地缓存,不相等就返回新的资源
    • 如果没有Etag,才看Last-modified的值,检查Last-modified是否等于最新的If-None-Since的值,如果相等直接走浏览器本地缓存,不相等就返回新的资源

1.4 - 缓存返回值

  • 200(from memory cache)
    • 命中强制缓存
    • 缓存来自于内存
  • 200(from disk cache)
    • 命中强制缓存
    • 缓存来自于磁盘
  • 304 Not Modified
    • 命中协商缓存
  • 200
    • 没有命中缓存

1.5-浏览器缓存机制详解流程图

在这里插入图片描述

1.6-总结缓存策略

  1. 强制缓存(优先级更高)
    • Expires cache-control
    • 不会重新发送请求,直接走缓存
  2. 协商缓存
    • last-modified和etag if-modified-since和if-None-Match
    • 通常和cache-control配合使用,no-cached,会再次发送请求,由服务器判断请求资源是否走缓存,
      • 如果走 返回 304 Not Modefined
      • 如果不走缓存 返回新的资源

1.7-cache缓存案例

const express = require('express');
const { resolve } = require('path');
const { readFile, stat, watchFile } = require('fs');
const etag = require('etag');
const app = express();
/*缓存:强制缓存http 1.1 cache-controlhttp 1.0 expires特点:在缓存的期限内,不会发送请求,直接读取缓存协商缓存响应头(服务器发给浏览器)etag 文件唯一标识last-modified 文件最近一次修改时间请求头if-none-match 文件唯一标识if-modified-since 文件最近一次修改时间流程:第一次浏览器访问服务器资源: 服务器设置响应头并返回资源给浏览器etag xxxlast-modified xxx浏览器接受到服务器返回的响应头,就会存储起来。第二次浏览器访问服务器资源,自动携带上之前存的响应头,作为请求头发送过去(会改名字)etag --> if-none-mathlast-modified --> if-modified-since服务器判断服务器保存的etag和浏览器发送过来if-none-math的值是否相等判断服务器保存的last-modified和浏览器发送过来if-modified-since的值是否相等如果都相等,走协商缓存  304如果有一个不相等,说明资源发生过变化,返回新资源特点:一定会访问服务器(一定发送请求),由服务器决定是否走缓存当强制缓存和协商缓存都存在:先看强制缓存。命中了,就直接读取缓存如果强制缓存失效(过期了),看协商缓存*/app.get('/', (req, res) => {// 访问当前路由,返回index.html// sendFile方法默认设置强制缓存、协商缓存// res.sendFile(resolve(__dirname, 'public/index.html'));const filePath = resolve(__dirname, 'public/index.html');readFile(filePath, (err, data) => {if (!err) {// 返回响应res.end(data);} else {console.log(err);}});
});// 强制缓存
app.get('/js/index.js', (req, res) => {const filePath = resolve(__dirname, 'public/js/index.js');readFile(filePath, (err, data) => {if (!err) {// 设置强制缓存  设置响应头res.set('cache-control', 'max-age=20');// res.set('expires', new Date(Date.now() + 10000).toGMTString());// 返回响应res.end(data);} else {console.log(err);}});
});let etagName = '';
let lastModified = 0;const filePath = resolve(__dirname, 'public/css/index.css');// 监视文件的变化
watchFile(filePath, (curr, prev) => {// 说明文件发生了变化,修改etagName/lastModifiedetagName = etag(curr);lastModified = new Date().toGMTString();
});
// 读取文件,获取初始化etagName, lastModified
stat(filePath, (err, stats) => {if (!err) {etagName = etag(stats);lastModified = new Date().toGMTString();}
});// 协商缓存
app.get('/css/index.css', (req, res) => {// 就要和etag对比const ifNoneMatch = req.headers['if-none-match'];// 就要和lastModified对比const ifModifiedSince = req.headers['if-modified-since'];if (ifNoneMatch === etagName && ifModifiedSince === lastModified) {// 都相等,走缓存res.status(304).end();return}// 返回新资源readFile(filePath, (err, data) => {if (!err) {// 设置协商缓存// 接受浏览器发送过的etag和last-modified。 与当前的值对比。 如果一样,走缓存,不一样就返回最新的资源res.set('etag', etagName);res.set('last-modified', lastModified);// 返回响应res.end(data);} else {console.log(err);}});
});app.listen(3000, (err) => {if (!err) console.log('服务器启动成功了~');else console.log(err);
});

1.8举个栗子看缓存

在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/qdCxCKXx.shtml

相关文章

浏览器缓存机制(HTTP缓存机制)

不废话,直接上干货,配图解说 首先浏览器首次请求一个网站,网站除了会返回我们需要资源,同时也会返回一些标识信息,这些标识信息约定了客户端和服务端的一些操作,这里列举重要的: 1.cache-contr…

HTTP的缓存机制

前面的话 缓存机制可以有很多种:比如客户端缓存、服务端缓存、代理服务器缓存等。 而本文主角HTTP的缓存是浏览器缓存。为什么这么说,下面来详细介绍一下。 HTTP缓存分类 HTTP缓存可以分为强缓存 与协商缓存。 强制缓存 当缓存数据库中已经有所请求…

HTTP 缓存机制详解

文章目录 HTTP Cache什么是 HTTP Cache关键字简单流程图代码准备不设置明确禁止缓存private与public缓存过期策略1、三种方式设置服务器告知浏览器缓存过期时间2、两种方式校验资源过期 强制校验缓存性能优化期中总结:HTTP 缓存性能检查清单前端工程化参考附代码 HT…

HTTP缓存机制与CDN

前提:周末看视频了解到一个关键词,http缓存,然后顺带这了解了一下cdn web应用程序的缓存大致分为数据库缓存,服务器端缓存(redis以及CDN 等缓存)、本地缓存。 本地缓存还包含很多内容:http缓存&…

浏览器http缓存机制

1、前言 前端缓存主要是分为HTTP缓存和浏览器缓存。其中HTTP缓存是在HTTP请求传输时用到的缓存,主要在服务器代码上设置;而浏览器缓存则主要由前端开发在前端js上进行设置。 http缓存是web缓存的核心,是最难懂的那一部分,也是最重要的那一部分。 2、H…

Http缓存机制与原理

一 Http缓存基本概念 1.1 Http报文 在浏览器和服务器进行Http通信时发送的数据即为Http报文,其中分为两部分: header - 报文的首部或头部,其中保存着各类请求的属性字段,关于Http的缓存相关规则信息均保存在header中body - 请求…

前端基础-浏览器缓存/HTTP缓存机制(面试常考)

文章目录 一、HTTP报文1.HTTP请求(Request)报文2.HTTP响应(Response)报文 二、缓存过程分析三、缓存规则1.强制缓存1.1Expires1.2 Cache-Control1.3例子 2. 缓存存储3.协商缓存3.1 Last-Modified / If-Modified-Since3.2 Etag / If-None-Match 四、不同刷新的请求执行过程五、总…

一文理解http缓存机制

HTTP报文 浏览器的缓存机制也就是我们所说的HTTP缓存机制,是根据HTTP报文的缓存标识进行的。先了解下HTTP报文: 请求报文 报文格式:请求行 – 请求头(通用信息头,请求头,实体头) – 请求体(只有POST才有请求体) 响…

http缓存机制

http缓存机制 1. 什么是缓存2. 缓存主要目的3. http缓存概述3.1 强缓存3.2 协商缓存 1. 什么是缓存 缓存(cache)是数据交换的缓冲区,是临时存储数据的仓库,在有大量数据交换的应用程序中,我们会采取一些方式将那些实时…

HTTP缓存机制及原理详解(最全)

前言 缓存技术是无数WEB开发从业人员在工作过程中不可避免的一大问题。在产品开发的时候我们总是想办法避免缓存产生,而在产品发布之时又在想策略管理缓存提升网页的访问速度。了解浏览器的缓存命中原理,是开发WEB应用的基础,本文着眼于此&a…

HTTP缓存机制详解

HTTP缓存机制详解 一. 前言二. 缓存的介绍什么是缓存?为什么要使用缓存?1. 减少冗余的数据传输2. 缓解带宽瓶颈3. 破坏瞬间拥塞4. 降低距离时延 三. 缓存有效性命中和未命中的再验证命中率字节命中率区分响应来自缓存还是服务器 四. 缓存拓扑结构私有缓存…

redis消息订阅与发布

一、消息订阅与发布 消息的订阅和发布是进程间的一种消息通信模式,发送者(pub)发送消息,订阅者(sub)接收消息。 二、常用命令示例 先订阅后发布,才能收到消息 执行SUBSCRIBE可以一次性订阅多个 执行PUBLISH命令,发布消息 …

redis发布与订阅

一、什么是发布和订阅 发布订阅是一种应用程序(系统)之间通讯,传递数据的技术手段。特别是在异构(不同语言)系统之间作用非常明显。发布订阅可以是实现应用(系统)之间的解耦合。 发布订阅&…

redis的发布和订阅

1、什么是发布和订阅 redis发布订阅(pub/sub)是一种消息通信模式:发布者(pub)发布消息,订阅者(sub)接收消 息。 redis客户端可以订阅任意数量的频道。 2、redis的发布和订阅 1、客户…

Redis——Redis 的发布和订阅

Redis 的发布和订阅 文章目录 Redis 的发布和订阅1、什么是发布和订阅2、Redis 的发布和订阅3、发布订阅命令行实现 1、什么是发布和订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。 Redis 客户端可…

Redis如何实现发布订阅功能

Redis如何实现发布订阅功能 文章目录 Redis如何实现发布订阅功能前言一、Redis发布订阅功能1. 发送消息2. 订阅某个频道3. 发布订阅的实现4. 总结 前言 Redis提供了发布订阅功能,可以用于消息的传输,Redis的发布订阅机制包括三个部分,发布者…

Java实现Redis的发布和订阅

Redis上的操作: 打开两个窗口,打开redis客户端: 一个客户端:订阅(客户端订阅channel1频道):127.0.0.1:6379> subscribe channel1 另一个客户端:发布(客户端向channel1频道发送消…

redis 发布订阅以及使用场景

redis 发布订阅 发布订阅模式:一个发布者多个订阅者只要选择订阅这个发布者,发布者发布的数据都可以被订阅到,只有订阅者开始订阅之后,发布的数据才可以接收,也就是说历史数据不能接收 127.0.0.1:6379> PUBLISH 163 hello (i…

Redis---订阅和发布

目录 消息系统命令 消息系统 ​ 发布/订阅,即 pub/sub,是一种消息通信模式:发布者也称为消息生产者,生产和发送消息到存储系统;订阅者也称为消息消费者,从存储系统接收和消费消息。这个存储系统可以是文件系…

Redis:Redis消息的发布与订阅(了解)

为了实现客户端的通信,提供了频道的概念 1.Redis发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis 客户端可以订阅任意数量的频道。 Redis发布订阅示意图 图一:消息订阅者…